微軟SQL Server是很多企業的理想選擇,新的版本通常更快更強大,我們也會迫不及待把老版本資料庫升級為新版本,這無可厚非,通常也非常順利,在老版本中備份資料庫,然後在新版本資料庫中恢複一下就可以了,微軟自己的東西,相容性通常不是問題,但有時我們需要回到低版本,比如客戶只有低版本的資料庫等情況,如果我們要把高版本的Database Backup,然後用低版本資料庫來還原,通常是不現實的,升級容易降級難.
這時,我們自然想到了,用指令碼來實現,指令碼可以完成表/視圖/預存程序/函數等建立工作,卻無法把資料也匯入進來,如果資料庫中有幾百張表,手工匯入資料將會是一場夢魘,為此,我通過一段代碼來實現了自動匯入功能,具體步驟如下:
1.在低版本資料庫中,建立一個到高版本資料庫的連結,如果你沒有使用過連結的伺服器,那就百度一下吧,很簡單的
2.用sql server的Management studio串連到高版本資料庫上,配置一下選項,"SQL Server物件總管"→"編寫指令碼"中,去掉"包含說明性標題"/"編寫USE<資料庫>指令碼"/"編寫if not exists 子句",勾選"編寫索引指令碼",注意"為伺服器版本編寫指令碼"選擇低版本資料庫對應的版本,其他選項可以根據實際情況進行設定.
3.在低版本資料庫中建立一個資料庫,名稱和高版本中的一樣
4.回到高版本資料庫,選擇全部的使用者表(按F7開啟物件總管詳細資料),點滑鼠右鍵,選擇建立指令碼,這時,我們欣喜的發現,建立的指令碼分為前後兩部分,前面部分是建立了表結構,後面部分對每張表添加約束/關聯等資訊,我們先把前面部分複製下來,粘貼到低版本資料庫裡面執行,這樣,就建立了表結構.
5.在低版本資料庫中執行下面的指令碼,將資料從高版本匯入:
--設定連結資料庫名
DECLARE @LinkDB NVARCHAR(100)
SELECT @LinkDB='[192.168.1.102,3000].[Station_Center]'
--建立一個表變數,存放所有使用者表名稱
DECLARE @tb TABLE(TableName NVARCHAR(50))
INSERT @tb
select [name] int from sysobjects where xtype='U' order by [name]
--定義需要執行的SQL語句、當前操作的表名、表中是否有識別欄位
DECLARE @Sql NVARCHAR(3000),@tbName NVARCHAR(50),@IsISIDENTITY BIT
--通過遊標,逐一對各表進行資料匯入
declare scu_Ticks CURSOR LOCAL FORWARD_ONLY READ_ONLY STATIC
for select TableName from @tb
open scu_Ticks
fetch from scu_Ticks into @tbName
while (@@fetch_status=0)
BEGIN
--檢查是有識別欄位,如果有,先關閉
IF EXISTS(SELECT *
FROM SYSCOLUMNS A INNER JOIN SYSOBJECTS D ON
A.ID=D.ID AND D.XTYPE='U' AND D.NAME<>'DTPROPERTIES'
WHERE D.NAME=@tbName AND COLUMNPROPERTY( A.ID,A.NAME,'ISIDENTITY')=1
)
BEGIN
SET @IsISIDENTITY=1
END
ELSE
BEGIN
SET @IsISIDENTITY=0
END
SELECT @Sql='
Truncate TABLE '+@tbName
IF @IsISIDENTITY =1
--有識別欄位,先臨時關閉
BEGIN
SET @Sql=@Sql+'
SET IDENTITY_INSERT '+@tbName+' ON
'
END
--從連結資料庫匯入資料
SET @Sql=@Sql+'
insert into '+@tbName+'
select * from '+ @LinkDB+'.dbo.'+@tbName
IF @IsISIDENTITY =1
--恢複標識
BEGIN
SET @Sql=@Sql+'
SET IDENTITY_INSERT '+@tbName+' OFF
'
END
EXEC(@Sql)--執行組合的SQL語句
fetch next from scu_Ticks into @tbName
end
close scu_Ticks
deallocate scu_Ticks
6.現在,表中有資料了,再把第4步中生產的指令碼的後半部分複製過來執行一下,這樣,表之間的關聯/約束就有了
7.最後,將視圖/函數/預存程序等其他內容通過指令碼建立起來.
其實,我們真正需要解決的是如何將資料自動匯入,其他的,都是通過自動產生的指令碼來實現的