SQL數據庫遷移:從低版到高版本


搬運出處:     https://www.cnblogs.com/Geton/p/5329989.html

  我見過太多的數據庫管理員花大量的時間在數據庫遷移上,即便在客戶的實際環境亦是如此。由於微軟頻繁的發布新版,基於業務和客戶的要求,應用服務不得不同時升級。當然,還有許多用戶仍在使用SQL Server 2000 (n 2005)的版本,這些都是接下來的不久需要升級的潛在用戶。這里我將提供最簡單,也是最快的解決方案把系統停機的時間降到最低。

  有很多方式方法去升級之前的數據庫,有人采用數據庫備份恢復的方式,從一個數據庫實例備份,然后恢復到另一個實例,這可是個耗時的過程,如果我們只有幾個數據庫需要升級的話還算好,可是假如我們需要升級的是50+甚至是100+個數據庫呢?很好,這里將介紹的是最合理的解決方案去減輕這樣的管理工作。

  為了最大限度的減少系統停機時間,我們開始升級前需准備好一切事前准備工作,還需要有升級后執行的和出錯時回滾的腳本。盡量避免采用GUI去更改實例或數據庫的配置,不再多述了,我們開始吧。 -- 我將會在每一個部分盡量的多寫備注。

  現假定我們需要把SQL2005實例升級到2012/2014,同樣從2000到2008/2008R2的步驟也是一樣的。

  請仔細閱讀和按步驟執行:

升級前准備清單

  1. 確保目標服務器有足夠的硬盤空間用於存放所有的數據庫文件。
  2. 確保所需要的端口全部打開。
  3. 確保SQL實例排列方式與源實例相同或者符合應用程序要求。
  4. 如果有一個數據庫使用了全文索引 -- 請參考文章后面的引用。
  5. DTS包的升級並不包含在內。
  6. 以下帖出的在目標服務器運行的腳本中只考慮單一LDF文件的情況,如果你有多個LDF文件,要么移除它,要么把它包含在腳本里面。而多個NDF's在所有的腳本里是有考慮到的。
  7. 仔細閱讀每一部分的注釋(包括腳本中的參數)
  8. 按應用和要求正確的更新參數(目標服務器名,共享文件夾,兼容級別等)。

重要提醒:腳本1-8和步驟2須預先執行並保存好,如果腳本的輸出的內容要符合目標應用的要求,那么腳本可能需要稍做一些更改。

步驟 1:

  1.  獲取源服務器的數據實例和數據庫的配置信息,保存其結果到EXCEL文件中以做升級之用。 

Sheet 1 -   

sp_helpdb

 Sheet 2 -  

select  * from master.sys.master_files

Sheet 3 -  

select * from master.sys.configurations -- To run on SQL 2005 and above.                    
sp_configure -- To run on SQL 2000 (enable show advanced options and rerun).

Sheet 4 -    

SELECT * FROM master.sys.sysfulltextcatalogs

 STEP 2:

  導出所有logins, jobs, linked servers, operators和系統數據庫中的用戶對象,SQL MAIL或者DATABASE MAIL等

對於導出登陸對象,請參考以下鏈接

從鏈接中得知,先在源實例中創建sp_help_revlogin存儲過程,然后拷貝其結果。

注: 需刪除系統帳戶,只拷貝所需的帳戶。

http://support.microsoft.com/kb/918992
http://support.microsoft.com/kb/246133

導出作業和其它的對象

確認哪些作業和哪些對象需要遷移到目標服務器。你可以打開SSMS,定位到所需要導出的對象,然后在對象資源管理器中選中對象,導出腳本到新窗口或文件,然后保存,其它對象類似,然后這些導出的腳本需要在目標服務器的SSMS中運行。

STEP 3:

  提供的 t-sql 腳本 [# 1 to # 8] 必須在源服務器中執行從而產生目標服務器執行的腳本,這一動作可以在幾天/星期前完成。在具體執行期間,這個產生的腳本將會在目標服務器上執行。

復制代碼
/*============================================================
Script 1 - 產生分離數據庫腳本

重要注釋: 在源服務器上執行以下語句以在結果窗口產生分離數據庫腳本。保存這個結果。萬一目標服務器需要回滾,此腳本同樣適用。 增加了參數 @keepfulltextindexfile='true' 以防某一用戶數據庫采用了全文檢索索引目錄,下一版本中,將會取消此參數 分離命令將會在以下情況中不能正常執行 如果你的數據庫用於同步,其必須停止發布。 必須刪掉的有的快照才能分離數據庫。 數據庫處於鏡像會話,必須停止。 質疑的數據庫不能被分離,除非你更改緊急模式。
Author : Dathuraj Pasarge Last Edited : 2nd June 2014 ===============================================================*/ declare @dbname varchar(150) declare @cmd varchar(250) IF CURSOR_STATUS('global','dbcursor')>=-1 BEGIN CLOSE dbcursor DEALLOCATE dbcursor END declare dbcursor cursor for select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks') -- Include any additional databases in NOT IN clause to exclude the databases from detach. Open dbcursor Fetch next from dbcursor into @dbname WHILE @@FETCH_STATUS = 0 BEGIN Begin set @cmd='sp_detach_db '+''''+@dbname+'' +''',''true''' print @cmd print 'go' End Fetch next from dbcursor into @dbname END close dbcursor deallocate dbcursor
復制代碼

output:

復制代碼
/*===============================================================
Script 2 : 生成腳本 - 生成重新附加數據庫的腳本。以防需要回滾。

 
注意事項
----------------------
在源服務器上運行,然后保存輸出的結果用於重新附加數據庫。此舉以防在升級過程中,出現一些不可預見性的錯誤。
 
Note: Scripts for Rolling back the change.
 
Author : Dathuraj Pasarge.
Last Edited : 2nd June 2014
================================================================*/
declare @dbname nvarchar(450)
declare @cmd nvarchar(1200)
declare @mdf nvarchar(800)
declare @ldf nvarchar(800)
 
DECLARE @serverVersion varchar(50)
select @serverVersion = CONVERT(varchar(50),SERVERPROPERTY('ProductVersion'))
SET @serverVersion = LEFT(@serverVersion, CHARINDEX('.', @serverVersion) - 1)
 
 
 
IF CURSOR_STATUS('global','dbcursor')>=-1
BEGIN
CLOSE  dbcursor
 DEALLOCATE dbcursor
 
END
 
If  convert(int,@serverVersion)<9
    
BEGIN
declare dbcursor cursor for
 
select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
-- Include the db's in NOT IN clause, which are suspect or inaccessible.
 
Open dbcursor
 
Fetch next from dbcursor into @dbname
 
WHILE @@FETCH_STATUS = 0
BEGIN
    Begin
set @mdf = RTRIM((select [filename] from master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=1))
set @ldf= RTRIM((select [filename] from master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=2))
 
set @cmd='sp_attach_db '+''''+@dbname+''','+ ''''+@mdf+''','''+@ldf+''''
 
    print @cmd
    print 'go'
    End
 
Fetch next from dbcursor into @dbname
END
 
close dbcursor
deallocate dbcursor
        END
    ELSE  
If  convert(int,@serverVersion)>=9    
BEGIN
    declare dbcursor cursor for
 
select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
-- Include the db's in NOT IN clause, which are suspect or inaccessible.
 
Open dbcursor
 
Fetch next from dbcursor into @dbname
 
WHILE @@FETCH_STATUS = 0
BEGIN
    Begin
 
set @mdf = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=1
and type_desc='ROWS'
)
set @ldf = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=2
and type_desc='LOG')
 
set @cmd='sp_attach_db '+''''+@dbname+''','+ ''''+@mdf+''','''+@ldf+''''
 
print @cmd
    print 'go'
    End
 
        Fetch next from dbcursor into @dbname
    END
close dbcursor
deallocate dbcursor
END
復制代碼

output:

復制代碼
/*==========================================================
Script 3 : 產生拷貝命令
 
注意事項 :
源服務器上運行
以下腳本產生拷貝命令,把數據文件和日志文件復制到目標服務器上
設置@DestinationServerName變量為目標服務器名,同樣需設置目標服務器的共享文件夾,其權限必須符可讀可寫
 
Author : Dathuraj Pasarge
Last Edited : 10th Dec 2014
==============================================================*/
 
declare @dbname nvarchar(150)
declare @cmd NVARCHAR(2000)
declare @MDFSourceFile nvarchar(500)
declare @LDFSourceFile varchar(500)
declare @NDFSourceFile nvarchar(500)
declare @MDFdestinationPath nvarchar(800)
declare @LDFdestinationPath nvarchar(800)
declare @DestinationServerName nvarchar(200)
declare @DestinationShareFolderMDF nvarchar(200)
declare @DestinationShareFolderLDF nvarchar(200)
declare @count1 int, @count2 int, @fileid int
 
set @DestinationServerName='SQL02' -- Update destination serverName
set @DestinationShareFolderMDF='Share1' -- Update ShareFolder created on destination server, for copying all mdf files
set @DestinationShareFolderLDF='Share2' -- Update ShareFolder created on destination server, for copying all ldf files
 
set @MDFdestinationPath='\\'+@DestinationServerName+'\'+@DestinationShareFolderMDF+'\MSSQL\DATA'  -- update folder names as per your requirement
 
set @LDFdestinationPath='\\'+@DestinationServerName+'\'+@DestinationShareFolderLDF+'\MSSQL\Logs'  -- update folder names as per your requirement
 
IF CURSOR_STATUS('global','dbcursor')>=-1
BEGIN
CLOSE  dbcursor
 DEALLOCATE dbcursor
 END
 
DECLARE @serverVersion varchar(50)
select @serverVersion = CONVERT(varchar(50),SERVERPROPERTY('ProductVersion'))
SET @serverVersion = LEFT(@serverVersion, CHARINDEX('.', @serverVersion) - 1)
 
If  convert(int,@serverVersion)>=9
BEGIN
declare dbcursor cursor for
select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')  
-- Include the db's in NOT IN clause, which are suspect or inaccessible.
 
Open dbcursor
Fetch next from dbcursor into @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
 
    set @MDFSourceFile = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=1)    -- For MDF Files
    set @cmd='XCOPY '+'"'+@MDFSourceFile+ '" "' +@MDFdestinationPath+ '"'
    PRINT @cmd
 
    set @LDFSourceFile = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=2) -- For LDF Files
    set @cmd='XCOPY '+'"'+@LDFSourceFile+ '" "' +@LDFdestinationPath+ '"'
    PRINT @cmd
 
    set @count1 = (select count(physical_name) from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id>2)
    set @count2=1
    set @fileid=3
    WHILE (@count2<=@count1)
    BEGIN
                set @NDFSourceFile = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=''+@fileid+'' )  
                set @cmd='XCOPY '+'"'+@NDFSourceFile+ '" "' +@MDFdestinationPath+ '"'    
                set @count2=@count2+1
                set @fileid=@fileid+1
                PRINT @cmd                            
    END
    Fetch next from dbcursor into @dbname
    PRINT ''
    END
 
END
 
If  convert(int,@serverVersion)<9
BEGIN
declare dbcursor cursor for
select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')  
-- Include the db's in NOT IN clause, which are suspect or inaccessible.
 
Open dbcursor
Fetch next from dbcursor into @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
 
    set @MDFSourceFile = RTRIM((SELECT [filename] FROM master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=1))    -- For MDF Files
    set @cmd='XCOPY '+'"'+@MDFSourceFile+ '" "' +@MDFdestinationPath+ '"'
    PRINT @cmd
 
    set @LDFSourceFile = RTRIM((SELECT [filename] FROM master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=2)) -- For LDF Files
    set @cmd='XCOPY '+'"'+@LDFSourceFile+ '" "' +@LDFdestinationPath+ '"'
    PRINT @cmd
 
    set @count1 = (SELECT count([filename]) FROM master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid>2)
    set @count2=1
    set @fileid=3
    WHILE (@count2<=@count1)
    BEGIN
                set @NDFSourceFile = RTRIM((SELECT [filename] FROM master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=''+@fileid+'' ))  
                set @cmd='XCOPY '+'"'+@NDFSourceFile+ '" "' +@MDFdestinationPath+ '"'    
                set @count2=@count2+1
                set @fileid=@fileid+1
                PRINT @cmd                            
    END
    Fetch next from dbcursor into @dbname
    PRINT ''
    END
 
    END
 
close dbcursor
deallocate dbcursor
復制代碼

Output

 

復制代碼
/*==============================================================
Script 4 : 產生腳本 - 用於目標服務器附加數據庫的

注意事項:
源服務器運行以下腳本, 產生附加數據庫腳本用於目標服務器。
取得所有的次數據庫文件(.ndf).
如果存在次日志文件,其路徑需手動包含到輸出結果中。
在目標服務器運行前,請保文件有效



Author - Dathuraj Pasarge.
Last Modified Date: 28th Nov 2014.
===========================================================*/
declare @dbname nvarchar(500)
declare @FileName nvarchar(500)
declare @cmd nvarchar(2000)
declare @MdfPath nvarchar(500)
declare @LdfPath nvarchar(500)
declare @count int, @count2 int
declare @fileid int

/* IMP NOTE - Set the below paths as per your environment for mdf and ldf location on the destination server*/
set @MdfPath='D:\MSSQL\DATA\' 
set @LdfPath='E:\MSSQL\Logs\'

IF CURSOR_STATUS('global','dbcursor')>=-1
BEGIN
CLOSE  dbcursor
DEALLOCATE dbcursor
END

declare dbcursor cursor for
select db_name(dbid),RTRIM([filename])  from master..sysaltfiles where dbid>4 
and db_name(dbid) not in ('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks') 
and  dbid<>32767 and fileid=1  -- Include the db's in NOT IN clause, which are suspect or inaccessible or not in scope.

Open dbcursor

Fetch next from dbcursor into @dbname,@FileName

WHILE @@FETCH_STATUS = 0
BEGIN

Begin

set @FileName= REVERSE(left(@FileName, CHARINDEX('.mdf', @FileName) + 4))
set @FileName= reverse(left(@FileName, CHARINDEX('\', @FileName) -1 ))
SET @cmd='exec sp_attach_db '+''''+@dbname+''''+', '+''''+@MdfPath+''+@FileName+''','

SET @FileName=RTRIM((SELECT filename from master..sysaltfiles where fileid=2 and db_name(dbid)=@dbname))
set @FileName= REVERSE(left(@FileName, CHARINDEX('.ldf', @FileName) + 4))
set @FileName= reverse(left(@FileName, CHARINDEX('\', @FileName) -1 ))
SET @cmd=@cmd + ''''+@LdfPath+''+@FileName+''''

set @count=(SELECT COUNT(*) from master..sysaltfiles where fileid>2 and db_name(dbid)=@dbname)

set @count2 =1
set @fileid=3
while(@count2<=@count)
begin
SET @FileName=RTRIM((SELECT filename from master..sysaltfiles where fileid=''+@fileid+'' and db_name(dbid)=@dbname))
set @FileName= REVERSE(left(@FileName, CHARINDEX('.ndf', @FileName) + 4))
set @FileName= reverse(left(@FileName, CHARINDEX('\', @FileName) -1 ))
SET @cmd=@cmd + ','''+@MdfPath+''+@FileName+''''
set @fileid=@fileid+1; 
set @count2=@count2+1;
end
print @cmd
print 'go'

End
Fetch next from dbcursor into @dbname,@FileName
PRINT ''
END

close dbcursor
deallocate dbcursor
 
復制代碼

output

 

復制代碼
/*=================================================================
Script 5 : 更改數據庫兼容等級
 
在源服務器上運行, 同時保存執行的結果。
查詢輸出在目標服務器上執行
 
設置@cmptlevel變量,不同的數據代表不同的版本
90 for SQL 2005, 100 for SQL 2008 and 2008 R2, 110 for SQL 2012 and 120 for SQL 2014.
 
Author : Dathuraj Pasarge
Last Edited : 14th July 2014
==================================================================*/
 
declare @dbname varchar(250)  
declare @cmptlevel varchar(10)
declare @Counter int
declare @cmd varchar(250)
 
-- Set Counter to Zero
Select @Counter = 0
 
SET @cmptlevel = 110  -- Change compatibility 90 for SQL 2005, 100 for SQL 2008 and 2008 R2, 110 for SQL 2012 and 120 for SQL 2014.
 
IF CURSOR_STATUS('global','dbcursor')>=-1
BEGIN
CLOSE  dbcursor
 DEALLOCATE dbcursor
 END
 
declare dbcursor cursor for
select sd.name  from master..sysdatabases sd
where sd.dbid>4 and sd.name not in('ReportServer','ReportServerTempDB',
'pubs','Northwind','AdventureWorks') -- Include databases with readonly,offline ones in this NOT IN clause, or make them online.
 
Open dbcursor
 
Fetch next from dbcursor into @dbname
 
WHILE @@FETCH_STATUS = 0
BEGIN
 
Begin
 
set @cmd='alter database '+ @dbname+ ' set compatibility_level = '+ @cmptlevel
Select @Counter = @Counter + 1
 
print @cmd
End
 
Fetch next from dbcursor into @dbname
END
 
close dbcursor
deallocate dbcursor
復制代碼

output

復制代碼
/*=============================================================
Script 6 : 更新數據庫usage。
 
注意事項 –
源服務器上運行,保存查詢輸出
查詢輸出在目標服務器上執行
只有從SQL2000的數據庫上升級才需要執行
 
Author : Dathuraj Pasarge
Last Edited : 14th July 2014
===============================================================*/
 
DECLARE @SQL VARCHAR(1000)  
DECLARE @DB sysname  
 
IF CURSOR_STATUS('global','dbcursor')>=-1
BEGIN
CLOSE  dbcursor
 DEALLOCATE dbcursor
 END
 
DECLARE curDB CURSOR FORWARD_ONLY STATIC FOR
 
SELECT [name] FROM master..sysdatabases WHERE dbid>4 and [name] not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')  ORDER BY [name]  -- Include the db's in NOT IN clause, which are suspect or inaccessible.
 
OPEN curDB  
    FETCH NEXT FROM curDB INTO @DB  
    WHILE @@FETCH_STATUS = 0  
BEGIN  
        
    SELECT @SQL = 'USE [' + @DB +']' + CHAR(13) + 'DBCC updateusage(0)' + CHAR(13)  
        
        PRINT @SQL  
          
    FETCH NEXT FROM curDB INTO @DB     
 
END  
    
CLOSE curDB  
DEALLOCATE curDB
復制代碼

output

 

復制代碼
/*=============================================================
Script 7 : 產生腳本 - 更新所有數據庫的統計信息
 
注意事項:
源服務器上執行,然后保存結果用於目標服務器上執行
 
Author : Dathuraj Pasarge
Last Edited : 14th July 2014
===============================================================*/
 
DECLARE @SQL VARCHAR(1000)  
DECLARE @DB sysname  
 
IF CURSOR_STATUS('global','dbcursor')>=-1
BEGIN
CLOSE  dbcursor
 DEALLOCATE dbcursor
 END
 
DECLARE curDB CURSOR FORWARD_ONLY STATIC FOR
SELECT [name] FROM master..sysdatabases WHERE dbid>4 and  [name] NOT IN ('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
                    ORDER BY [name] -- Include the db's in NOT IN clause, which are suspect or inaccessible.
 
OPEN curDB  
    FETCH NEXT FROM curDB INTO @DB  
    WHILE @@FETCH_STATUS = 0  
BEGIN        
    SELECT @SQL = 'USE [' + @DB +']' + CHAR(13) + 'EXEC sp_updatestats' + CHAR(13)         
        PRINT @SQL           
    FETCH NEXT FROM curDB INTO @DB  
    
END  
    
CLOSE curDB  
DEALLOCATE curDB
復制代碼

output

 

復制代碼
/*============================================================
Script 8 : 產生腳本 - 更改數據庫所屬
 

 
Author : Dathuraj Pasarge
===============================================================*/
 
declare @dbname varchar(250)  
declare @login varchar(250)  
declare @cmd varchar(250)
 
IF CURSOR_STATUS('global','dbcursor')>=-1
BEGIN
CLOSE  dbcursor
 DEALLOCATE dbcursor
 END
 
declare dbcursor cursor for
select sd.name, suser_sname(sd.sid) from master..sysdatabases sd
where sd.dbid>4 and sd.name NOT IN ('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks') -- Include the db's in NOT IN clause, which are suspect or inaccessible.
 
Open dbcursor
 
Fetch next from dbcursor into @dbname,@login
 
WHILE @@FETCH_STATUS = 0
BEGIN
Begin
 
print 'use ' + @dbname
set @cmd='exec sp_changedbowner '+''''+@login+''''
print @cmd
End
 
Fetch next from dbcursor into @dbname,@login
END
 
close dbcursor
deallocate dbcursor
復制代碼

output

在正式升級的時候請按以下腳本和步驟執行。

  1. 備份所有系統和用戶數據庫
  2. 停止有關應用程序的服務。
  3. 刪除所有源實例連接進程。
復制代碼
/*=========================================================================
Script 9 :
殺掉所有源服務器連接進程
 
分離數據庫前,請運行以下腳本殺掉現有連接進程
 
 Author : Dathuraj Pasarge.
Last Modified Date: 10th Nov 2014.
 =========================================================================*/
DECLARE @kill varchar(4000)  
set @kill= '';
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), spid) + ';'
FROM master..sysprocesses  
WHERE spid >50 and spid<>(select @@SPID)
EXEC(@kill);
go  
use master
go
sp_who2;
go
復制代碼

  4. 分享所有源服務器的數據庫

  執行 Script # 1 的查詢結果

  5. 生成XCOPY命令復制源服務器的所有主數據文件,日志文件到目標服務器上,生成的命令在以管理員身份運行的命令提示符下運行。

  執行 Script # 3 的查詢結果

  注意: 對比數據庫文件的個數,如果存在多於一個ldf文件的數據庫,記得手動添加相應的命令。

  6. 在目標服務器附加所有數據庫

  執行 Script # 4 的查詢結果

  7. 附加完畢后,需確保所有數據庫在線且可以訪問

  8.在附加過程中如果出錯,請確保數據庫所有文件均復制到目標數據庫且確保與你腳本的路徑一致

  9.執行創建登陸,作業,連接服務器,操作員腳本以創建相應的對象

  10. 修復孤立用戶。

復制代碼
/*===========================================================
Script 10 - Fix Orphaned users.
Notes:
1. 以下腳本修復所有數據庫的孤立用戶
2. 當你創建了所有登陸用戶后,運行以下腳本去除孤立用戶.
 
Author: Dathuraj Pasarge
==========================================================*/
 
SET NOCOUNT ON
If exists (select * from sysobjects where name like '#databases%')
 DROP TABLE #databases
 if exists (select * from sysobjects where name like '#orphanusers%')
 DROP TABLE #orphanusers
BEGIN
 
declare @username sysname,
@DBName varchar(250),
@NoOfUsers smallint,
@Query1 varchar(2000),
@Query2 varchar(2000)
 
CREATE TABLE #orphanusers
(
rowid smallint IDENTITY(1,1),
UserName sysname,
UserSID varbinary(100)
)
 
CREATE TABLE #databases
(
dbname varchar(250)
)
 
INSERT INTO #databases SELECT name from master.sys.databases where database_id > 4 and state_desc = 'ONLINE'
 
WHILE EXISTS(SELECT 1 FROM #databases)
 
BEGIN
 
 SET @Query1 = ''
 
 SELECT TOP 1 @DBName = dbname FROM #databases ORDER BY dbname
 
 SET @Query1 = 'EXEC ' + @DBName + '.dbo.sp_change_users_login ''report'''
 
 INSERT INTO #orphanusers EXEC(@Query1)
 
  WHILE EXISTS(SELECT 1 FROM #orphanusers)
BEGIN
SELECT TOP 1 @username = UserName
FROM #orphanusers ORDER BY rowid
 
BEGIN TRY
SET @Query2 = 'EXEC ' + @DBName + '.dbo.sp_change_users_login ''Update_One'',' + @username+ ',' + @username
EXEC(@Query2)
Print 'Orphaned user ' + @username + ' fixed in ' +@DBName +' database'
END TRY
 
BEGIN CATCH
 
PRINT 'Login '+ @username + ' has not found. If needed , create it and fix the orphaned issue. '
 
END CATCH
      DELETE FROM #orphanusers WHERE UserName = @username
END
      DELETE FROM #databases WHERE dbname = @DBName
END
 
DROP TABLE #orphanusers
DROP TABLE #databases
 
END
復制代碼

  11. 更改數據庫兼容級別

  執行 Script # 5 查詢輸出

  12. 更改所有用戶數據庫所屬對象.  

  執行 Script # 6 查詢輸出

  13. 更新數據庫usage

  執行 Script # 7 查詢輸出

  14. 更新數據庫統計信息

  執行 Script # 8 查詢輸出

遷移后須檢查事項

  如果你發現應用程序響應慢了,同時又有足夠的停機時間,試着重建所有索引和維護計划或者那些你認為可行的辦法.

1. 檢查SQL Server錯誤日志

2. 如果你在附加數據庫的時候出現以下錯誤,以管理員身份打開SSMS

操作系統錯誤5: "5(failed to retrieve text for this error. Reason: 15105)".

3. 如果不能解析主機名,試着刷新一下IP地址和DNS緩存

4. 如果有用到ODBC,確保ODBC連接可用。

5. 確保所有連接服務器可用.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM