2009-05-15 20 views
39

को पुनर्स्थापित करने के बाद उपयोगकर्ताओं को लॉग इन करने के लिए लिंक करना मैं दो सर्वरों के बीच डेटाबेस को स्थानांतरित करना चाहता हूं, मैंने पहले सर्वर से डेटाबेस का बैक अप लिया है और दूसरे सर्वर पर डेटाबेस पुनर्स्थापना किया है, अब तक इतना अच्छा है।SQL सर्वर 2005 डेटाबेस

हालांकि हमारा एप्लिकेशन डेटाबेस में परिभाषित कई डेटाबेस उपयोगकर्ताओं का उपयोग करता है। इन्हें मास्टर डेटाबेस में परिभाषित लॉग इन से जोड़ा जाना चाहिए। सर्वर मैंने डेटाबेस को पुनर्स्थापित किया है जिसमें सभी लॉग इन परिभाषित हैं, हालांकि उनके पास अलग-अलग सिड्स हैं।

मैं टी-एसक्यूएल विशेषज्ञ नहीं हूं ...।

मुझे लगता है कि sp_change_users_login समाधान का हिस्सा है, लेकिन मैं कैसे यह स्वचालित रूप से एक ही नाम के लॉगिन के लिए बहाल डेटाबेस में सभी उपयोगकर्ताओं से जोड़ने के लिए प्राप्त करने के लिए बाहर नहीं मिल रहा।

हमारे द्वारा उपयोग किए जाने वाले डेटाबेस निर्माण स्क्रिप्ट्स उपयोगकर्ता और लॉग इन बनाते हैं, हालांकि यह लॉगिन बनाते समय एसआईडी निर्दिष्ट नहीं करता है, इसलिए यह समस्या है। अब अगर मेरे पास टाइम मशीन थी ...

(जब मैं Google को बहुत सारी हिट प्राप्त करता हूं, हालांकि वे अधिकतर साइटें हैं जो आपको पहले साइट पर पंजीकरण किए बिना उत्तर नहीं देगी।)

+0

भी देखें इस सवाल http://stackoverflow.com/प्रश्न/22 9 883/सिंक-एसक्यूएल-लॉग इन-यूटिलिटी-ऑन-2005-2008 – Cruachan

उत्तर

28

इस घटना को "अनाथाश्रित उपयोगकर्ता" कहा जाता है।

यहाँ यह बारे में एक लेख है और यह कैसे तय करने के लिए:

http://sqlblog.com/blogs/eric_johnson/archive/2008/10/17/fixing-orphaned-users.aspx

और यहाँ पुस्तकें ऑनलाइन आदेश के बारे में लेख है:

http://msdn.microsoft.com/en-us/library/aa259633(SQL.80).aspx

+1

यह विधि वास्तव में SQL सर्वर 2008 के रूप में बहिष्कृत है: http://msdn.microsoft.com/en-us/library/ms143729(v=sql.100).aspx। इसके बजाय ALTER USER का उपयोग करें। –

+2

आपकी जानकारी के लिए, परिवर्तन के लिए वाक्यविन्यास है ... ALTER USER LOGIN = pperrin

+0

हमने पाया है कि SQL2014 में, यह चरण अब आवश्यक नहीं है। डेटाबेस को बहाल करने के बाद, लॉग इन स्वचालित रूप से उपयोगकर्ताओं के साथ फिर से जुड़े होते हैं। – Mike

1

मुझे Microsoft KB918992 से निम्न स्क्रिप्ट मिली - इसे मूल सर्वर पर चलाएं और यह 'sp_help_revlogin' नामक संग्रहित प्रक्रिया तैयार करेगी जो गंतव्य सर्वर पर चलाने के लिए एक और स्क्रिप्ट उत्पन्न करती है, जो सभी उपयोगकर्ता खातों को एक ही पासवर्ड और सिड्स के साथ बनाती है। 2008.

USE master 
GO 
IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL 
    DROP PROCEDURE sp_hexadecimal 
GO 
CREATE PROCEDURE sp_hexadecimal 
    @binvalue varbinary(256), 
    @hexvalue varchar(256) OUTPUT 
AS 
DECLARE @charvalue varchar(256) 
DECLARE @i int 
DECLARE @length int 
DECLARE @hexstring char(16) 
SELECT @charvalue = '0x' 
SELECT @i = 1 
SELECT @length = DATALENGTH (@binvalue) 
SELECT @hexstring = 'ABCDEF' 
WHILE (@i <= @length) 
BEGIN 
    DECLARE @tempint int 
    DECLARE @firstint int 
    DECLARE @secondint int 
    SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1)) 
    SELECT @firstint = FLOOR(@tempint/16) 
    SELECT @secondint = @tempint - (@firstint*16) 
    SELECT @charvalue = @charvalue + 
    SUBSTRING(@hexstring, @firstint+1, 1) + 
    SUBSTRING(@hexstring, @secondint+1, 1) 
    SELECT @i = @i + 1 
END 
SELECT @hexvalue = @charvalue 
GO 

IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL 
    DROP PROCEDURE sp_help_revlogin 
GO 
CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS 
DECLARE @name sysname 
DECLARE @xstatus int 
DECLARE @binpwd varbinary (256) 
DECLARE @txtpwd sysname 
DECLARE @tmpstr varchar (256) 
DECLARE @SID_varbinary varbinary(85) 
DECLARE @SID_string varchar(256) 

IF (@login_name IS NULL) 
    DECLARE login_curs CURSOR FOR 
    SELECT sid, name, xstatus, password FROM master..sysxlogins 
    WHERE srvid IS NULL AND name <> 'sa' 
ELSE 
    DECLARE login_curs CURSOR FOR 
    SELECT sid, name, xstatus, password FROM master..sysxlogins 
    WHERE srvid IS NULL AND name = @login_name 
OPEN login_curs 
FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @xstatus, @binpwd 
IF (@@fetch_status = -1) 
BEGIN 
    PRINT 'No login(s) found.' 
    CLOSE login_curs 
    DEALLOCATE login_curs 
    RETURN -1 
END 
SET @tmpstr = '/* sp_help_revlogin script ' 
PRINT @tmpstr 
SET @tmpstr = '** Generated ' 
    + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */' 
PRINT @tmpstr 
PRINT '' 
PRINT 'DECLARE @pwd sysname' 
WHILE (@@fetch_status <> -1) 
BEGIN 
    IF (@@fetch_status <> -2) 
    BEGIN 
    PRINT '' 
    SET @tmpstr = '-- Login: ' + @name 
    PRINT @tmpstr 
    IF (@xstatus & 4) = 4 
    BEGIN -- NT authenticated account/group 
     IF (@xstatus & 1) = 1 
     BEGIN -- NT login is denied access 
     SET @tmpstr = 'EXEC master..sp_denylogin ''' + @name + '''' 
     PRINT @tmpstr 
     END 
     ELSE BEGIN -- NT login has access 
     SET @tmpstr = 'EXEC master..sp_grantlogin ''' + @name + '''' 
     PRINT @tmpstr 
     END 
    END 
    ELSE BEGIN -- SQL Server authentication 
     IF (@binpwd IS NOT NULL) 
     BEGIN -- Non-null password 
     EXEC sp_hexadecimal @binpwd, @txtpwd OUT 
     IF (@xstatus & 2048) = 2048 
      SET @tmpstr = 'SET @pwd = CONVERT (varchar(256), ' + @txtpwd + ')' 
     ELSE 
      SET @tmpstr = 'SET @pwd = CONVERT (varbinary(256), ' + @txtpwd + ')' 
     PRINT @tmpstr 
    EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT 
     SET @tmpstr = 'EXEC master..sp_addlogin ''' + @name 
      + ''', @pwd, @sid = ' + @SID_string + ', @encryptopt = ' 
     END 
     ELSE BEGIN 
     -- Null password 
    EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT 
     SET @tmpstr = 'EXEC master..sp_addlogin ''' + @name 
      + ''', NULL, @sid = ' + @SID_string + ', @encryptopt = ' 
     END 
     IF (@xstatus & 2048) = 2048 
     -- login upgraded from 6.5 
     SET @tmpstr = @tmpstr + '''skip_encryption_old''' 
     ELSE 
     SET @tmpstr = @tmpstr + '''skip_encryption''' 
     PRINT @tmpstr 
    END 
    END 
    FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @xstatus, @binpwd 
    END 
CLOSE login_curs 
DEALLOCATE login_curs 
RETURN 0 
GO 
+0

गंतव्य सर्वर में पहले से ही सभी लॉगिन बनाए गए हैं, हालांकि पोस्ट करने के लिए धन्यवाद ई स्क्रिप्ट यह अन्य लोगों के लिए उपयोगी होगी –

+0

यह प्रक्रिया भी अच्छी है क्योंकि यह SQL सर्वर लॉगिन के एसआईडी को सुरक्षित रखती है ताकि वे लक्ष्य सर्वर पर समान बनाए जाएं। लॉग शिपिंग जैसे परिदृश्यों में बहुत उपयोगी है। –

37

हाँ के लिए SQL2000 से हमारे उन्नयन के लिए चमत्कार काम किया, तो आप उस से क्रियान्वित कर सकते हैं:

EXEC sp_change_users_login 'Auto_Fix' , 'TheUserName'; 

लेकिन अगर आपके सवाल था मैं सभी उपयोगकर्ताओं को ठीक कर सकते स्वचालित रूप से तो यह काम नहीं चलेगा उस।

1

मैं एक अच्छा स्क्रिप्ट है कि आप डेटाबेस उपयोगकर्ताओं से लॉग इन बनाने के लिए उपयोग कर सकते हैं, जो कि इस समस्या को खोजने के बाद मैं आया था यह स्क्रिप्ट एक संग्रहीत प्रक्रिया का उपयोग कर रही है। आप कुछ अन्य उपयोगी स्क्रिप्ट यहाँ भी इस यूआरएल http://www.sqlserveroptimizer.com/2011/08/how-to-script-logins-from-user-database-in-sql-server-20052008-r2/

USE MyDatabaseName 

DECLARE @login nvarchar(50) 

DECLARE logins_cursor CURSOR FOR SELECT l.name FROM sys.database_principals u INNER JOIN sys.server_principals l ON u.sid=l.sid 

OPEN logins_cursor FETCH NEXT FROM logins_cursor INTO @login 

WHILE @@FETCH_STATUS = 0 BEGIN EXEC sp_help_revlogin @login FETCH NEXT FROM logins_cursor INTO @login END 

CLOSE logins_cursor DEALLOCATE logins_cursor GO 
25

मैं निम्नलिखित के साथ आया था पर पा सकते हैं। यह बहुत अच्छा काम करता है क्योंकि यह आपको पता चलता है:

  1. सभी मौजूदा अनाथ उपयोगकर्ताओं।
  2. कौन सा तय किया गया था।
  3. कौन सा तय नहीं किया जा सका।

अन्य समाधानों को आपको ठीक करने के लिए हाथ से पहले अनाथ उपयोगकर्ता नाम जानने की आवश्यकता है।

निम्न कोड किसी ऐसे सर्वर पर चलाया जा सकता है जिसे किसी अन्य सर्वर पर डेटाबेस बहाल करने के बाद कहा जाता है।

स्क्रिप्ट:

EXEC sp_change_users_login 'report'--See all orphaned users in the database. 
DECLARE @OrphanedUsers TABLE 
(
    IndexKey Int IDENTITY(1,1) PRIMARY KEY, 
    UserName SysName,--nVarChar(128) 
    UserSID VarBinary(85) 
) 
INSERT INTO @OrphanedUsers 
    EXEC sp_change_users_login 'report' 

DECLARE @CRLF as nVarChar 
    SET @CRLF = CHAR(10) + '&' + CHAR(13)--NOTE: Carriage-Return/Line-Feed will only appear in PRINT statements, not SELECT statements. 
DECLARE @Sql as nVarChar(MAX) 
    SET @Sql = N'' 
DECLARE @IndexKey as Int 
    SET @IndexKey = 1 
DECLARE @MaxIndexKey as Int 
    SET @MaxIndexKey = (SELECT COUNT(*) FROM @OrphanedUsers) 
DECLARE @Count as Int 
    SET @Count = 0 
DECLARE @UsersFixed as nVarChar(MAX) 
    SET @UsersFixed = N'' 
DECLARE @UserName as SysName--This is an orphaned Database user. 

WHILE (@IndexKey <= @MaxIndexKey) 
    BEGIN 
    SET @UserName = (SELECT UserName FROM @OrphanedUsers WHERE IndexKey = @IndexKey) 
    IF 1 = (SELECT COUNT(*) FROM sys.server_principals WHERE Name = @UserName)--Look for a match in the Server Logins. 
     BEGIN 
     SET @Sql = @Sql + 'EXEC sp_change_users_login ''update_one'', [' + @UserName + '], [' + @UserName + ']' + @CRLF 
     SET @UsersFixed = @UsersFixed + @UserName + ', ' 
     SET @Count = @Count + 1 
     END 
    SET @IndexKey = @IndexKey + 1 
    END 

PRINT @Sql 
EXEC sp_executesql @Sql 
PRINT 'Total fixed: ' + CAST(@Count as VarChar) + '. Users Fixed: ' + @UsersFixed 
SELECT ('Total fixed: ' + CAST(@Count as VarChar) + '. Users Fixed: ' + @UsersFixed)[Fixed] 
EXEC sp_change_users_login 'report'--See all orphaned users still in the database. 

परिणाम:

enter image description here

* ध्यान दें: 4, जिन्हें ठीक नहीं किया गया है (ऊपर मेरी उदाहरण स्क्रीनशॉट में) एक इसी उपयोगकर्ता नहीं था गंतव्य सर्वर में डेटाबेस को पुनर्स्थापित किया गया था।

+3

दोस्त, यह आश्चर्यजनक है! बहुत बढ़िया। – CrazyTim

+2

यह मेरे लिए बहुत अच्छा काम करता है, कुछ हद तक उपयोगकर्ताओं (और मिलान करने वाले लॉग इन वे अनाथ थे) को छोड़कर उनके नाम पर एकल उद्धरण था (मुझे आश्चर्य हुआ कि वे कानूनी भी थे!)। मैंने 'उपयोगकर्ता नाम' के बजाय [उपयोगकर्ता नाम] पास करने के लिए sp_change_users_login पर पास किए गए पैरा को बदल दिया और फिर उन उपयोगकर्ताओं ने भी काम किया (और 'सामान्य' वाले भी उस परिवर्तन के बाद ठीक से तय किए गए थे। धन्यवाद, @ माइकटीवी एक महान लिपि के लिए! –

+0

यह हमलावर द्वारा एक शानदार प्रयास होगा, और शायद इसके खिलाफ सुरक्षा के लायक नहीं है - लेकिन वैसे भी चेतावनी के रूप में: '']; ड्रॉप टेबल उपयोगकर्ता; 'एक वैध SQL उपयोगकर्ता नाम है जिसका उपयोग बुराई के लिए किया जा सकता है। संपादित करें: संभवतः डीबीए इसे उठा लिया है, लेकिन मैंने पर्याप्त ऐप्स देखे हैं जो उपयोगकर्ताओं को अपना स्वयं का डीबी उपयोगकर्ता नाम बनाने देते हैं। – Squid