解析 SID 作为参数

Parse SID as a parameter

我在 Microsoft SQL 2019 中有 2 个包含的数据库。在 DB01 中,已创建一个具有密码的用户:

USE DB01
CREATE USER [username] WITH PASSWORD = '1234'

在DB02中,没有login/password的用户需要用相同的SID创建。 如果我 运行 命令并手动填写 SID,它可以正常工作:

USE DB02
CREATE USER [username] WITHOUT LOGIN WITH DEFAULT_SCHEMA = [schema_1], SID = 0x010500000000000903000000AD91E331ECFC284B938E65DAF644BAF6

但是,如果我尝试将 SID 解析为参数,它会失败并出现错误“'@usersid' 附近的语法不正确”

USE DB01
DECLARE @usersid varbinary(MAX) = (SELECT sid FROM sys.sysusers WHERE name = 'username')
USE DB02
CREATE USER [username] WITHOUT LOGIN WITH DEFAULT_SCHEMA = [schema_1], SID = @usersid

知道为什么吗?

编辑

根据@Stephan 的建议(非常感谢!!!),我提出了以下解决方案。我不得不稍微修改查询,因为数据库名称实际上也来自变量。我不知道这是否是最好的方法,但它有效:)

DECLARE @DB01 nvarchar(30) = 'DB01'
DECLARE @DB02 nvarchar(30) = 'DB02'

DECLARE @usersid varbinary(85)
DECLARE @get_sid nvarchar(max) = 'SELECT @usersid = sid FROM ' + @DB01 + '.sys.database_principals WHERE [name] = ''username'''
EXEC sp_executesql @get_sid, N'@usersid varbinary(85) OUTPUT', @usersid OUTPUT

DECLARE @create_user nvarchar(max) = CONCAT(N'USE ',@DB02,N' CREATE USER [username] WITHOUT LOGIN WITH DEFAULT_SCHEMA = [dbo],SID = ',CONVERT(NVARCHAR(MAX),@usersid,1))
EXEC(@create_user)

正如其他人提到的,您必须使用动态 SQL 因为 CREATE USER 不是设计来接受输入参数,只能接受文字字符串。

动态SQL 以创建具有特定 SID 的用户

DECLARE @UserSID varbinary(85) = (SELECT sid FROM sys.database_principals WHERE [name] = N'UserName');

DECLARE @SQL NVARCHAR(MAX) = CONCAT(N'CREATE USER [username] WITHOUT LOGIN WITH DEFAULT_SCHEMA = dbo,SID = ',CONVERT(NVARCHAR(MAX),@UserSID,1))

EXEC(@SQL)