【发布时间】:2018-06-01 00:13:15
【问题描述】:
我正在尝试通过 LinkdedServers 聚合 SQL Server 用户,但无法在我的查询中选择数据库名称。我尝试在我的选择语句中使用db_name() as ''Database'',但它使用当前数据库上下文,而不是我从中选择的数据库。我意识到发生这种情况是因为我使用的是“完全限定”的数据库名称,因此数据库上下文实际上从未改变。我也无法将光标值作为我的选择语句的一部分。
有人对我如何获取我选择的数据库的数据库名称有任何想法吗?
这是我的代码:
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'.
在这种情况下如何将变量变成字符串?
【问题讨论】:
-
你有数据库名称...在变量中。而不是 db_name 使用 ' + @DatabaseName + ' 作为数据库
-
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'。
-
你必须把它变成一个字符串。可能只需要 '' 在字符串文字的每一侧。您可以在问题中发布您的代码吗? cmets 中的格式化很糟糕。
-
Sean Lange,我将代码添加到问题中。感谢您的观看!
标签: sql-server cursor dynamic-sql linked-server