如何更改登录名和在存储过程中创建的数据库的数据库所有者?

Pet*_*ith 5 sql-server-2008 sql-server stored-procedures

我有一个签名的存储过程,它创建一个新数据库、一个新登录名并将新用户分配为新数据库的所有者。那么我的存储过程会创建新的登录名和新数据库,但不会将新用户分配为新数据库的所有者。存储过程位于应用程序数据库中,而不是 master。

我得到的错误是:

找不到主体“BlahUser”,因为它不存在或您没有权限。

存储过程在具有有限权限(在存储过程上执行)的不同登录名 (simpleUser) 下执行。

证书用户具有以下权限:

  • 创建任何数据库
  • 更改任何登录

有问题的代码是:

SET @sqlStmt = 'ALTER AUTHORIZATION ON DATABASE::'+@sessionid+'Data TO ['+@orgName+'User]'

SET @metasql = '
USE [master]
EXEC (''' + REPLACE(@sqlStmt, '''', '''''') + ''')
'
EXEC sp_executesql @metasql
Run Code Online (Sandbox Code Playgroud)

我尝试像这样将执行用户(simpleUser)的模拟授予存储过程中的新用户,但它也会导致错误。我不确定创建其他用户的用户是否可以自动模拟他们。

SET @sqlStmt = 'GRANT IMPERSONATE ON LOGIN::'+@orgName+'User TO simpleUser';

SET @metasql = '
USE [master]
EXEC (''' + REPLACE(@sqlStmt, '''', '''''') + ''')
' 
EXEC sp_executesql @metasql
Run Code Online (Sandbox Code Playgroud)

小智 1

编写执行动态 SQL 的存储过程最适合我的方法是,当我开始编写存储过程时不使用“EXEC sp_executesql”,而是使用“PRINT”语句。

我确保能够看到存储过程生成的每条 SQL。我从“消息”选项卡复制它们并在 Management Studio 中执行它们。只有在所有 SQL 按预期工作之后,我才允许存储过程“EXEC sp_executesql”(而不是简单地打印 SQL 语句)。

通过这种方式调试速度非常快。到目前为止,我遇到的大多数问题都是由于缺少空格造成的,例如“FROMMyTableName”或“WHEREId = 12”。

您必须以证书用户身份或使用具有类似权限的帐户进行测试。如果可以避免使用动态 SQL,那就避免使用它们。