为什么调用sp_who的tsql存储过程在通过SqlCommnad调用时返回的结果与通过SSMS调用不同



我正试图编写一个存储过程来确定活动数据库上的连接数。我的存储过程目前如下:

CREATE PROCEDURE [dbo].[GetActiveUsers]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @who TABLE(spid SMALLINT, ecid SMALLINT, [status] NCHAR(30), loginame NCHAR(128), hostname NCHAR(128), blk CHAR(5), dbname NCHAR(128), cmd NCHAR(16), request_id INT);
INSERT INTO @who
exec sp_who 'FMApp'
--SELECT 99,98,'good','person','host','12345','db','1234567890123456',1
SELECT COUNT(*) AS [ActiveUsers] FROM @who; 
END

我之所以将sp_who的结果放入表变量中,是为了对结果进行进一步的筛选。为了调试,我暂时删除了筛选。

当我通过SQLServerManagementStudio调用这个存储过程时,它的行为与预期的一样,并且我得到一个非零值。然而,当我使用SqlCommand通过C#调用它时,它总是返回零。

调用代码:*注意:connectionService.Create返回一个打开的SqlConnection

using (var connection = connectionService.Create())
{
var activeUsersSql = "GetActiveUsers";
using (var command = new SqlCommand(activeUsersSql, connection))
{
command.CommandType = CommandType.StoredProcedure;
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
activeUsers = reader.GetInt32(0);
}
}
}
}

如果我更改存储过程以从sp_who以外的源填充表变量,那么对SSMS的调用和通过SqlCommand的调用都会对结果达成一致。

CREATE PROCEDURE [dbo].[GetActiveUsers]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @who TABLE(spid SMALLINT, ecid SMALLINT, [status] NCHAR(30), loginame NCHAR(128), hostname NCHAR(128), blk CHAR(5), dbname NCHAR(128), cmd NCHAR(16), request_id INT);
INSERT INTO @who
SELECT 99,98,'good','person','host','12345','db','1234567890123456',1
--exec sp_who 'FMApp'
SELECT COUNT(*) AS [ActiveUsers] FROM @who; 
END

是权限问题,是对sp_*过程使用的限制,还是我遗漏了一些明显的内容?

正如@DavidG所说,问题是权限问题。没有VIEW SERVER STATE权限,您只能查看自己的会话。我筛选的用户与我运行流程的用户不同,所以它总是为零。

若要查看或检索sp_who/sp_who2的结果,应具有view SERVER STATE权限。如果您使用管理员帐户通过C#应用程序连接到SQL server,它应该会返回数据。在应用程序中检查为用于连接SQL server的帐户分配的权限。

如果没有权限,用户将只能看到当前会话。

最新更新