One of the problems restoring a database to a new server is dealing with out of sync logins.
The link between a database user name and a server user name is the SID that is generated when the login is added to SQL Server.
There are stored procedures to sync the SID's but they have to be run for each user that is out of sync in each database.
the sp_msForEachDB system stored procedure. It is a handy procedure that will execute a batch of statements for every database on the server. The database name can be referenced in the script by using a ? as a placeholder
The link between a database user name and a server user name is the SID that is generated when the login is added to SQL Server.
There are stored procedures to sync the SID's but they have to be run for each user that is out of sync in each database.
the sp_msForEachDB system stored procedure. It is a handy procedure that will execute a batch of statements for every database on the server. The database name can be referenced in the script by using a ? as a placeholder
--First run this script to see if there are any logins that are out of sync. DECLARE @Collation VARCHAR(100) DECLARE @SQL VARCHAR(2000) CREATE TABLE ##TempSync ( DB_NME VARCHAR(50) ,DBUserName VARCHAR(50) ,SysLoginName VARCHAR(50) ) SELECT @Collation = CONVERT(SYSNAME, DatabasePropertyEx('master', 'Collation')) SET @SQL = 'USE [?] SELECT ''?'' DB_NME, A.name DBUserName,B.loginname SysLoginName FROM sysusers A JOIN master.dbo.syslogins B ON A.name Collate ' + @Collation + ' = B.Name JOIN master.dbo.sysdatabases C ON C.Name = ''?'' WHERE issqluser = 1 AND (A.sid IS NOT NULL AND A.sid <> 0x0) AND suser_sname(A.sid) IS NULL AND (C.status & 32) =0 --loading AND (C.status & 64) =0 --pre recovery AND (C.status & 128) =0 --recovering AND (C.status & 256) =0 --not recovered AND (C.status & 512) =0 --offline AND (C.status & 1024) =0 --read only ORDER BY A.name' INSERT INTO ##TempSync EXEC sp_msforeachdb @SQL SELECT * FROM ##TempSync DROP TABLE ##TempSync --If the first script returns data, run this script to sync the logins. DECLARE @Collation VARCHAR(100) DECLARE @SQL VARCHAR(2000) SELECT @Collation = CONVERT(SYSNAME, DatabasePropertyEx('master', 'Collation')) SET @SQL = 'USE [?] DECLARE @DBUserName varchar(50) DECLARE @SysLoginName varchar(50) DECLARE SyncDBLogins CURSOR FOR SELECT A.name DBUserName, B.loginname SysLoginName FROM sysusers A JOIN master.dbo.syslogins B ON A.name Collate ' + @Collation + ' = B.Name JOIN master.dbo.sysdatabases C ON C.Name = ''?'' WHERE issqluser = 1 AND (A.sid IS NOT NULL AND A.sid <> 0x0) AND suser_sname(A.sid) IS NULL AND (C.status & 32) =0 --Loading AND (C.status & 64) =0 --pre recovery AND (C.status & 128) =0 --recovering AND (C.status & 256) =0 --not recovered AND (C.status & 512) =0 --offline AND (C.status & 1024) =0 --read only ORDER BY A.name OPEN SyncDBLogins FETCH NEXT FROM SyncDBLogins INTO @DBUserName, @SysLoginName WHILE @@FETCH_STATUS = 0 BEGIN EXEC sp_change_users_login ''update_one'', @DBUserName, @SysLoginName FETCH NEXT FROM SyncDBLogins INTO @DBUserName, @SysLoginName END CLOSE SyncDBLogins DEALLOCATE SyncDBLogins' EXEC sp_msforeachdb @SQL
No comments:
Post a Comment