2010-05-20 68 views
0

執行數據庫恢復後,我想運行一個動態腳本來修復ophaned用戶。下面的腳本循環執行sp_change_users_login'report'後顯示的所有用戶,並使用login = [username]語句應用「alter user [username]」來修復SID衝突。我發現了一個「上線15不正確的語法錯誤」,不能弄清楚爲什麼...幫助..腳本動態修復數據庫恢復後的ophaned用戶

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 ‘[email protected]+‘ WITH LOGIN ‘[email protected] 
    EXECUTE(@cmd) 
    FETCH NEXT FROM userLogin_cursor INTO @Username 
    END 
CLOSE userLogin_cursor 
DEALLOCATE userLogin_cursor 

回答

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 
+0

我總是忘了括號[]。謝謝! – gates 2010-05-20 15:13:56

+0

您是否驗證過用戶確實存在? – Kenneth 2010-05-20 17:48:28

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] [email protected] 
SET @vsql = '[dbo].[sp_change_users_login] ''AUTO_FIX'',''' + @userName + '''' 
-- EXEC(@vsql) 
PRINT @vsql 
SET @UserCurr = @UserCurr + 1 
END 
+1

http://technet.microsoft.com/en-us/library/ms174378.aspx sp_change_users_login現已棄用,應改用Alter User – DevDave 2013-05-29 16:31:13

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