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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在动态SQL(SQL Server)中的Select语句中使用游标值相关的知识,希望对你有一定的参考价值。

我试图通过LinkdedServers聚合SQL Server用户,但我无法在查询中选择数据库名称。我尝试在我的select语句中使用db_name() as ''Database'',但它使用当前的数据库上下文,而不是我选择的数据库。我意识到发生这种情况是因为我使用的是“完全限定”的数据库名称,因此数据库上下文永远不会实际更改。我也无法将游标值作为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]'

以上是关于如何在动态SQL(SQL Server)中的Select语句中使用游标值的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server如何防止动态sql中的sql注入

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

如何从 C# 动态运行 SQL Server CE [Windows mobile] 中的 SQL 脚本文件?

如何从 SQL Server 中的动态节点加载 OPENJSON

如何从 SQL Server Express 中的动态查询创建 RDLC 报告

如何在SQL Server 2012中动态替换表中的所有值?