當前位置:開發者網絡 >> 技術教程 >> 數據庫專欄 >> SQL Server >> 內容
精彩推薦
分類最新教程
分類熱點教程
    
如何在正運行 SQL Server 7.0 的服務器之間傳輸登錄和密碼
作者:未知
日期:2005-04-29
人氣:
投稿:(轉貼)
來源:未知
字體:
收藏:加入瀏覽器收藏
以下正文:
SQL Server 7.0 數據轉換服務 (DTS) 對像傳輸功能可在兩台服務器之間傳輸登錄和用戶,但它不傳輸 SQL Server 驗證登錄的密碼。要從一台運行 SQL Server 7.0 的服務器向另一台運行 SQL Server 7.0 的服務器傳輸登錄和密碼,請按照本文“在 Master 數據庫中創建和運行存儲過程”一節中的說明操作。您將在源服務器上創建 sp_help_revlogin 存儲過程。此過程將生成一個腳本,您可以在目標服務器上運行該腳本,以重新創建帶有原始安全標識號 (SID) 的登錄,並保留當前的密碼。

返回頁首

如何從 SQL Server 7.0 向 SQL Server 2000 或者在正運行 SQL Server 2000 的服務器之間傳輸登錄和密碼要從 SQL Server 7.0 服務器向 SQL Server 2000 的一個實例或者在 SQL Server 2000 的兩個實例之間傳輸登錄和密碼,可以使用 SQL Server 2000 中新的 DTS Package Transfer Logins Task(DTS 包傳輸登錄任務)。要使用此任務,請執行以下步驟:

1.連接到 SQL Server 2000 目標服務器,移動到 SQL Server 企業管理器中的數據轉換服務,展開此文件夾,右鍵單擊本地程序包,然後單擊新增程序包。2.在 DTS 程序包設計器打開後,單擊任務菜單上的傳輸登錄任務。根據需要完成有關源、目標和登錄選項卡的信息。

重要說明:SQL Server 2000 目標服務器不能運行 64 位版本的 SQL Server 2000。64 位版本 SQL Server 2000 的 DTS 組件不可用。如果要從其他計算機上的 SQL Server 實例中導入登錄,您的 SQL Server 實例必須在域帳戶下運行才能完成此任務。

注意:您可以使用 DTS 方法或本文“在 Master 數據庫中創建和運行存儲過程”一節中的腳本,從 SQL Server 7.0 向 SQL Server 2000 或者在 SQL Server 2000 的實例之間傳輸登錄。DTS 方法將傳輸密碼,但不傳輸原始 SID。如果登錄不是使用原始 SID 創建的,而且用戶數據庫也被傳輸到一台新服務器,則該數據庫用戶將被從該登錄中孤立出去。要傳輸原始 SID 並迴避孤立用戶,請使用本文下一節中的腳本代替 DTS 方法。返回頁首

在 Master 數據庫中創建和運行存儲過程請查看本文末尾的備註,以瞭解有關下列步驟的重要信息。
1.在源 SQL Server 上運行以下腳本。此腳本可在 master 數據庫中創建名稱分別為 sp_hexadecimal 和 sp_help_revlogin 的兩個存儲過程。請在創建完過程之後繼續執行第 2 步。

注意:下面的過程取決於 SQL Server 系統表。這些表的結構在 SQL Server 的不同版本之間可能會有變化,請不要直接從系統表中選擇。

----- Begin Script, Create sp_help_revlogin procedure -----USE masterGOIF OBJECT_ID ('sp_hexadecimal') IS NOT NULL DROP PROCEDURE sp_hexadecimalGOCREATE PROCEDURE sp_hexadecimal @binvalue varbinary(256), @hexvalue varchar(256) OUTPUTASDECLARE @charvalue varchar(256)DECLARE @i intDECLARE @length intDECLARE @hexstring char(16)SELECT @charvalue = '0x'SELECT @i = 1SELECT @length = DATALENGTH (@binvalue)SELECT @hexstring = '0123456789ABCDEF'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 + 1ENDSELECT @hexvalue = @charvalueGOIF OBJECT_ID ('sp_help_revlogin') IS NOT NULL DROP PROCEDURE sp_help_revloginGOCREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL ASDECLARE @name sysnameDECLARE @xstatus intDECLARE @binpwd varbinary (256)DECLARE @txtpwd sysnameDECLARE @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_nameOPEN login_cursFETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @xstatus, @binpwdIF (@@fetch_status = -1)BEGIN PRINT 'No login(s) found.' CLOSE login_curs DEALLOCATE login_curs RETURN -1ENDSET @tmpstr = '/* sp_help_revlogin script 'PRINT @tmpstrSET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */'PRINT @tmpstrPRINT ''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 ENDCLOSE login_cursDEALLOCATE login_cursRETURN 0GO ----- End Script -----
2.在創建 sp_help_revlogin 存儲過程之後,請從源服務器上的查詢分析器中運行 sp_help_revlogin 過程。sp_help_revlogin 存儲過程可同時用於 SQL Server 7.0 和 SQL Server 2000。sp_help_revlogin 存儲過程的輸出是登錄腳本,該腳本可創建帶有原始 SID 和密碼的登錄。保存輸出,然後將其粘貼到目標 SQL Server 上的查詢分析器中,並運行它。例如:
EXEC master..sp_help_revlogin
返回頁首

備註•在目標 SQL Server 上運行輸出腳本之前,請認真查看此腳本。如果必須將登錄傳輸到與 SQL Server 源實例不在同一個域中的 SQL Server 實例,請編輯由 sp_help_revlogin 過程生成的腳本,並在 sp_grantlogin 語句中將域名替換為新的域名。由於在新域中被授予訪問權的集成登錄與原域中的登錄具有不同的 SID,因此數據庫用戶將被從這些登錄中孤立出去。要解決這些孤立用戶,請參見以下項目符號項中引用的文章。如果在同一個域中的 SQL Server 實例之間傳輸集成登錄,則會使用相同的 SID,而且用戶不太可能被孤立。•在移動登錄之後,用戶將不再具有訪問已被同時移動的數據庫的權限。此問題稱為“孤立用戶”。如果嘗試將訪問此數據庫的權限授予該登錄,則可能會失敗,這表明該用戶已存在:
Microsoft SQL-DMO (ODBC SQLState:42000) Error 15023:User or role '%s' already exists in the current database.有關如何將登錄映射到數據庫用戶以解決孤立的 SQL Server 登錄和集成登錄的說明,請參見以下 Microsoft 知識庫文章: 240872 HOW TO:在 SQL 服務器之間移動數據庫時如何解決權限問題
有關使用 sp_change_users_login 存儲過程逐個解決孤立用戶(僅能解決從標準 SQL 登錄中孤立出去的用戶)的說明,請參見以下 Microsoft 知識庫文章: 274188 PRB: "Troubleshooting Orphaned Users" Topic in Books Online is Incomplete •如果傳輸登錄和密碼是向運行 SQL Server 的新服務器移動數據庫的一部分,請參見以下 Microsoft 知識庫文章,以瞭解對所涉及的工作流程和步驟的說明: 314546 HOW TO: Move Databases Between Computers That Are Running SQL Server •能夠這樣做的原因在於:sp_addlogin 系統存儲過程中的 @encryptopt 參數允許通過使用加密密碼來創建登錄。有關此過程的更多信息,請參見 SQL Server 聯機圖書中的“sp_addlogin (T-SQL)”主題。•默認情況下,只有 sysadminfixed 服務器角色的成員可以從 sysxlogins 表中進行選擇。除非 sysadmin 角色的成員授予了必要的權限,否則最終用戶將無法創建或運行這些存儲過程。•此方法不會嘗試傳輸特定登錄的默認數據庫信息,因為默認數據庫並不始終存在於目標服務器中。要為某個登錄定義默認數據庫,您可以使用 sp_defaultdb 系統存儲過程,並將登錄名和默認數據庫作為參數傳遞給該過程。有關使用此過程的更多信息,請參見 SQL Server 聯機圖書中的“sp_defaultdb”主題。•在 SQL Server 實例之間傳輸登錄的過程中,如果源服務器的排序順序不區分大小寫,而目標服務器的排序順序區分大小寫,則在將登錄傳輸到目標服務器後,必須在密碼中用大寫形式輸入所有字母字符。如果源服務器的排序順序區分大小寫,而目標服務器的排序順序不區分大小寫,則無法通過使用本文概述的過程傳輸的登錄進行登錄,除非原始密碼不包含字母字符,或者原始密碼中的所有字母字符都是大寫字符。如果兩個服務器都區分大小寫或者都不區分大小寫,則不會出現此問題。這是 SQL Server 處理密碼的方式所帶來的副作用。有關更多信息,請參見 SQL Server 7.0 聯機圖書中的“Effect on Passwords of Changing Sort Orders”(更改排序順序對密碼的影響)主題。•當在服務器上運行 sp_help_revlogin 腳本的輸出時,如果該服務器已經定義了一個登錄,且該登錄名與腳本輸出中的某個登錄的名稱相同,則在執行 sp_help_revlogin 腳本的輸出時,可能會看到下面的錯誤信息:


Server:Msg 15025, Level 16, State 1, Procedure sp_addlogin, Line 56
The login 'test1' already exists.

同樣,如果此服務器上存在其他登錄,且其 SID 值與您要嘗試添加的登錄相同,則會收到以下錯誤信息:


Server:Msg 15433, Level 16, State 1, Procedure sp_addlogin, Line 93
Supplied parameter @sid is in use.

因此,您必須仔細查看這些命令的輸出,檢查 sysxlogins 表的內容,並相應地解決這些錯誤。•特定登錄的 SID 值被用作在 SQL Server 中實現數據庫級別訪問的基礎。因此,如果同一登錄在該數據庫級別(在該服務器上的兩個不同數據庫中)有兩個不同的 SID 值,則此登錄將僅能訪問其 SID 與該登錄的 syslogins 中的值相匹配的數據庫。如果所討論的兩個數據庫已從兩個不同的服務器合併在一起,則可能出現這種情形。要解決此問題,需要使用 sp_dropuser 存儲過程從具有不匹配 SID 的數據庫中手動刪除所討論的登錄,然後再使用 sp_adduser 存儲過程添加它。
相關文章: