如何在 Dynamic SQL (SQL Server) 中的 Select 语句中使用游标值

How to use cursor value in Select Statement within Dynamic SQL (SQL Server)

我正在尝试通过 LinkdedServers 聚合 SQL 服务器用户,但无法在我的查询中 select 数据库名称。我尝试在我的 select 语句中使用 db_name() as ''Database'',但它使用当前数据库上下文,而不是我 select 来自的数据库。我意识到发生这种情况是因为我使用的是 "fully qualified" 数据库名称,因此数据库上下文从未真正改变过。我也无法将光标值作为我的 select 语句的一部分。

有没有人知道如何获取我 select 来自的数据库的数据库名称?

这是我的代码:

DECLARE @DatabaseName VARCHAR(30)

DECLARE c1 CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR
SELECT 
    Name 
FROM 
    [LinkedServer].master.sys.databases
WHERE 
    Name NOT IN     (
                    'master',
                    'model',
                    'tempdb',
                    'msdb',
                    'distribution',
                    )


OPEN c1

FETCH NEXT FROM c1 
INTO @DatabaseName

WHILE @@FETCH_STATUS = 0
BEGIN

EXEC (
'
--INSERT INTO [Gather_Privileged_DBUsers_Sox]
SELECT  distinct (dp.name) as ''DatabaseUser'', 
        s.name as ''ServerName'',
        db_name() as ''Database'', 
        getdate() as ''date''
FROM    [LinkedServer].[' + @DatabaseName + '].sys.database_role_members drm 
        JOIN [LinkedServer].[' + @DatabaseName + '].sys.database_principals dp
            ON drm.member_principal_id = dp.principal_id
        JOIN [LinkedServer].[' + @DatabaseName + '].sys.database_principals dp2
            ON  drm.role_principal_id = dp2.principal_id
        JOIN [LinkedServer].[master].[sys].[servers] s on 1=1
WHERE 
        dp2.name in 
(''db_owner'',''db_accessadmin'',''db_securityadmin'',''db_ddladmin'')
        AND s.server_id = 0
        AND dp.name not in (''dbo'')
        AND dp.type != ''R''
')

FETCH NEXT FROM c1 
INTO @DatabaseName
END 
CLOSE c1;
DEALLOCATE c1;
GO    

尝试使用变量值:

SELECT  distinct (dp.name) as ''DatabaseUser'', 
        s.name as ''ServerName'', 
        ' + @DatabaseName + ' as ''Database'', 
        getdate() as ''date''

当我这样做时,出现以下错误:Msg 207, Level 16, State 1, Line 5 Invalid column name 'myTestDatabase'.

在这种情况下如何将变量转换为字符串?

您应该改掉将列别名括在单引号中的习惯。它们不是字符串文字,这会使您的代码更难阅读。它还会引起很多动态 sql.

的痛苦

下面是一个示例,说明如何捕获变量中的值并构建没有这些额外单引号的字符串。

declare @SQL nvarchar(max) = 
'SELECT  distinct (dp.name) as DatabaseUser, 
        s.name as ServerName, 
        ''' + @DatabaseName + ''' as Database, 
        getdate() as [date]'