使用以下代码运行 SQL Server 2012 CLR 存储过程:
const string executeLog = "EXEC master..xp_logevent @errorNumber, @message, informational";
using (SqlCommand cmd = new SqlCommand(executeLog, connection))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@errorNumber", 60001);
cmd.Parameters.AddWithValue("@message", url);
cmd.ExecuteScalar();
}
我收到此错误:
System.Data.SqlClient.SqlException:对对象“xp_logevent”、数据库“mssqlsystemresource”、架构“sys”的执行权限被拒绝。
我尝试以sa
用户身份执行此操作:
grant execute on xp_logevent to sa
但我得到另一个错误:
您找不到不存在的用户“sa”或用户没有权限。
如何向 sa 用户授予执行权限?
您不需要在服务器角色中按
sa
原样授予执行任何内容,并且几乎可以做任何事情。因此,如果您在执行时遇到错误,那么您没有以. 连接字符串是使用还是常规/外部连接?如果使用,则权限基于执行 SQLCLR 存储过程的人。如果使用常规连接,则权限默认基于 SQL Server NT 服务的登录帐户(如果是默认实例,则为MSSQLSERVER / SQLEXPRESS ),否则它可以是执行 SQLCLR 存储过程的任何人的权限,如果代码已添加以进行模拟。sa
sysadmin
xp_logevent
sa
context connection = true;
context connection = true;
那么,它是如何制造的
SqlConnection
呢?该问题的答案将有助于确定适当的解决方案。如果此 SQLCLR 存储过程将由任何人(即不一定是db_owner
数据库角色或sysadmin
服务器角色的用户)调用,那么您可以执行以下操作以将此权限授予尽可能小的范围。在包含 SQLCLR 存储过程的数据库中:
db_owner
数据库角色dbo.LogEvent
),它接受您传入的两个参数 (@errorNumber
和@message
) 并简单地执行EXEC xp_logevent @errorNumber, @message, informational;
EXECUTE
将调用 SQLCLR 存储过程的任何用户和/或数据库角色dbo.LogEvent
),而不是xp_logevent
using
声明更改为new SqlCommand("dbo.LogEvent", connection)
cmd.CommandType = CommandType.Text;
为cmd.CommandType = CommandType.StoredProcedure;
const string executeLog
线其他注意事项:
AddWithValue
,因为它有问题。相反,只需SqlParameter
使用显式设置的数据类型创建 ,然后将其添加到SqlCommand.SqlParameters
集合中。ExecuteScalar
如果您没有从结果集中捕获某些内容,则无需调用。相反,调用ExecuteNonQuery
根据 MSDN,您需要具有以下权限
需要 master 数据库中 db_owner 固定数据库角色的成员身份,或 sysadmin 固定服务器角色的成员身份。