我有以下脚本,我希望能够针对除系统数据库之外的动态数据库列表运行此脚本。这很直截了当。棘手的一点是每个数据库可能有不同的用户列表来运行fix命令。这会是第三个游标吗?我的尝试下面没有正确填充每个数据库的用户。任何帮助将不胜感激。
SET nocount ON
GO
SET QUOTED_IDENTIFIER OFF
GO
--
-- Declare and define variables
--
DECLARE @databasename VARCHAR(50) -- database name
DECLARE @sqlcommand nvarchar(256) -- SQL Command generated
DECLARE db_cursor CURSOR FOR
SELECT NAME
FROM master.dbo.sysdatabases
WHERE NAME NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'DBATools' ) -- don't include the databases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @databasename
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Fixing Logins for '
+ Cast(@databasename AS VARCHAR)
DECLARE curSQL CURSOR FOR
SELECT "USE " + ( @databasename ) + ";" + " exec sp_change_users_login 'AUTO_FIX','" + NAME + "'"
SELECT NAME
FROM sys.sysusers
WHERE issqluser = 1
AND NAME NOT IN ( 'dbo', 'guest', 'INFORMATION_SCHEMA', 'sys' )
OPEN curSQL
FETCH curSQL INTO @sqlcommand
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @sqlcommand
EXEC (@sqlcommand)
FETCH curSQL INTO @sqlcommand
END
CLOSE curSQL
DEALLOCATE curSQL
FETCH NEXT FROM db_cursor INTO @databasename
END
CLOSE db_cursor
DEALLOCATE db_cursor
答案 0 :(得分:0)
与您的程序相关的主要是,与PHP不同,TSQL不能互换使用单引号和双引号。所以我修复了你的动态SQL字符串。
另一个小问题似乎是来自游标声明的脱节查询 - 在你的游戏声明中,你使用select子句跟随第二个声明,没有附带的from子句,它会抛出" Name&#34 ;无法找到该光标。所以我也解决了这个问题。
DECLARE @databasename SYSNAME, @sqlcommand nvarchar(max)
DECLARE db_cursor CURSOR FOR
SELECT NAME
FROM master.dbo.sysdatabases
WHERE NAME NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'DBATools' ) -- don't include the databases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @databasename
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Fixing Logins for '
+ Cast(@databasename AS VARCHAR)
DECLARE curSQL CURSOR FOR
SELECT 'USE ' + @databasename + ';' + ' exec sp_change_users_login ''AUTO_FIX'',''' + NAME + ''';'
FROM sys.database_principals
WHERE Type='S'
AND NAME NOT IN ( 'dbo', 'guest', 'INFORMATION_SCHEMA', 'sys' )
OPEN curSQL
FETCH curSQL INTO @sqlcommand
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @sqlcommand
--EXEC (@sqlcommand)
FETCH curSQL INTO @sqlcommand
END
CLOSE curSQL
DEALLOCATE curSQL
FETCH NEXT FROM db_cursor INTO @databasename
END
CLOSE db_cursor
DEALLOCATE db_cursor
编辑:每个评论将表交换到database_principals而不是sys.sysusers。
答案 1 :(得分:0)
或者你可以无光泽地做。
DECLARE @Output NVARCHAR(MAX)
SET @Output = ''
SELECT @Output = @Output +
'--Fixing Logins For ' + name + CHAR(10) +
'USE ' + name + CHAR(10) +
'EXEC sp_change_users_login ''AUTO_FIX'','''+
(
SELECT b.name
FROM sys.sysusers as b
WHERE issqluser = 1
AND b.name NOT IN ( 'dbo', 'guest', 'INFORMATION_SCHEMA', 'sys' )
)
+''''+CHAR(10)+CHAR(10)
FROM master.dbo.sysdatabases
WHERE NAME NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'DBATools' )
PRINT @Output