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

Sql server 如何在动态SQL(SQL Server)中的Select语句中使用游标值,sql-server,cursor,dynamic-sql,linked-server,Sql Server,Cursor,Dynamic Sql,Linked Server,我试图通过LinkdedServers聚合SQL Server用户,但无法在查询中选择数据库名称。我尝试在select语句中使用db_name()作为“数据库”,但它使用的是当前数据库上下文,而不是我正在选择的数据库。我意识到这是因为我使用的是“完全限定”的数据库名称,所以数据库上下文实际上从未更改。我也无法将光标值作为select语句的一部分拉入 有没有人对如何获取我正在选择的数据库的数据库名有什么想法 这是我的密码: DECLARE @DatabaseName VARCHAR(30) DE

我试图通过LinkdedServers聚合SQL Server用户,但无法在查询中选择数据库名称。我尝试在select语句中使用
db_name()作为“数据库”
,但它使用的是当前数据库上下文,而不是我正在选择的数据库。我意识到这是因为我使用的是“完全限定”的数据库名称,所以数据库上下文实际上从未更改。我也无法将光标值作为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,16级,状态1,第5行
列名“myTestDatabase”无效。


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

您应该改掉将列别名用单引号括起来的习惯。它们不是字符串文字,这使代码更难阅读。它也会给动态sql带来很多痛苦

下面是一个示例,说明如何在不使用额外单引号的情况下捕获变量中的值并构建此字符串

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

您的数据库名就在那里…在变量中。使用“++@DatabaseName+”作为数据库,而不是使用“++@DatabaseName+”作为数据库选择distinct(dp.name)作为“DatabaseUser”,s.name作为“ServerName”,“++@DatabaseName+”作为“Database”,getdate()作为“date”,我的语法可能是错误的,但当我尝试这样做时,我收到以下错误消息:Msg 207,级别16,状态1,第5行列名称“mytestDatabase”无效。必须将其设置为字符串。可能只需要将“”添加到字符串文字的每一侧。你能把你的密码写在问题里吗?评论中的格式很糟糕。肖恩·兰格,我在问题中添加了代码。谢谢你看!太棒了,非常感谢肖恩!我试过用双引号,但现在明白为什么我需要用三个记号了。我对t-sql比较陌生,在筛选文档以处理查询时遇到困难。我是在现有代码的基础上构建的,但将来会尽量避免这种类型的事情,因为它会让事情变得更加混乱