db恢复后动态修复孤立用户的脚本

时间:2010-05-20 08:58:46

标签: sql sql-server-2005

执行数据库还原后,我想运行动态脚本来修复被遮蔽的用户。我的脚本循环遍历执行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

3 个答案:

答案 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]'