执行数据库还原后,我想运行动态脚本来修复被遮蔽的用户。我的脚本循环遍历执行sp_change_users_login'report'后显示的所有用户,并应用“alter user [username] with login = [username]”语句来修复SID冲突。我在第15行得到“错误的语法错误”,无法弄清楚为什么......帮助..
DECLARE @Username varchar(100), @cmd varchar(100)
DECLARE userLogin_cursor CURSOR FAST_FORWARD
FOR
SELECT UserName = name FROM sysusers
WHERE issqluser = 1 and (sid IS NOT NULL AND sid <> 0×0)
AND suser_sname(sid) IS NULL
ORDER BY name
FOR READ ONLY
OPEN userLogin_cursor
FETCH NEXT FROM userLogin_cursor INTO @Username
WHILE @@fetch_status = 0
BEGIN
SET @cmd = ‘ALTER USER ‘+@username+‘ WITH LOGIN ‘+@username
EXECUTE(@cmd)
FETCH NEXT FROM userLogin_cursor INTO @Username
END
CLOSE userLogin_cursor
DEALLOCATE userLogin_cursor
答案 0 :(得分:3)
可以使用[dbo]。[sp_change_users_login]存储过程修复孤立用户。
遍历所有用户并执行程序
祝你好运
DECLARE @UserCount INT
DECLARE @UserCurr INT
DECLARE @userName VARCHAR(100)
DECLARE @vsql NVARCHAR(4000)
DECLARE @Users TABLE(
id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
userName VARCHAR(100))
INSERT INTO @Users(UserName)
SELECT [name] FROM
--
master.[dbo].sysUsers -- SQL 2008 & SQL 2005
--master.dbo.sysxlogins -- SQL 2000
SELECT @UserCount = max([id]) FROM @Users
SET @UserCurr = 1
WHILE (@UserCurr <= @UserCount)
BEGIN
SELECT @userName=userName FROM @Users WHERE [id] =@UserCurr
SET @vsql = '[dbo].[sp_change_users_login] ''AUTO_FIX'',''' + @userName + ''''
-- EXEC(@vsql)
PRINT @vsql
SET @UserCurr = @UserCurr + 1
END
答案 1 :(得分:1)
DECLARE @Username VARCHAR(100),
@cmd VARCHAR(100)
DECLARE userlogin_cursor CURSOR FAST_FORWARD FOR
SELECT username = name
FROM sysusers
WHERE issqluser = 1
AND (sid IS NOT NULL
AND sid <> 0x01)
AND Suser_sname(sid) IS NULL
ORDER BY name
FOR READ ONLY
OPEN userlogin_cursor
FETCH NEXT FROM userlogin_cursor INTO @Username
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = 'ALTER USER [' + @username + '] WITH LOGIN = [' + @username + ']'
EXECUTE(@cmd)
FETCH NEXT FROM userlogin_cursor INTO @Username
END
CLOSE userlogin_cursor
DEALLOCATE userlogin_cursor
答案 2 :(得分:1)
我使用了类似的方法,将代码包装在存储过程中:
USE [master]
GO
CREATE PROCEDURE [sp_AutoFixAllUsers]
AS
BEGIN
DECLARE @AutoFixCommand NVARCHAR(MAX)
SET @AutoFixCommand = ''
SELECT --dp.[name], dp.[sid] AS [DatabaseSID], sp.[sid] AS [ServerSID],
@AutoFixCommand = @AutoFixCommand + ' '
+ 'EXEC sp_change_users_login ''Auto_Fix'', ''' + dp.[name] + ''';'-- AS [AutoFixCommand]
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp
ON dp.[name] = sp.[name] COLLATE DATABASE_DEFAULT
WHERE dp.[type_desc] IN ('SQL_USER', 'WINDOWS_USER', 'WINDOWS_GROUP')
AND sp.[type_desc] IN ('SQL_LOGIN', 'WINDOWS_LOGIN', 'WINDOWS_GROUP')
AND dp.[sid] <> sp.[sid]
IF (@AutoFixCommand <> '')
BEGIN
PRINT 'Fixing users in database: ' + DB_NAME()
PRINT @AutoFixCommand
EXEC(@AutoFixCommand)
PRINT ''
END
END
GO
然后我使用sys.sp_MS_marksystemobject
存储过程使我的存储过程在所有用户数据库中可用(允许它在本地对象上运行)
EXEC sys.sp_MS_marksystemobject 'sp_AutoFixAllUsers'
然后您可以按如下方式运行它:
EXEC [MyDB].[dbo].[sp_AutoFixAllUsers]
或者对于使用sp_msforeachdb
的每个数据库:
EXEC sp_msforeachdb '[?].[dbo].[sp_AutoFixAllUsers]'