在SQL Server 中使用SQLDMO
曾幾何時(shí),伙伴們?yōu)閿?shù)據(jù)庫(kù)的升級(jí)傷透了腦筋.往往程序的升級(jí)趕不上數(shù)據(jù)庫(kù)的升級(jí)(版本控制的好,這也許不是什么問(wèn)題,但對(duì)于很大一部分中國(guó)公司來(lái)說(shuō)這是無(wú)法避免的).而有些n久以前的數(shù)據(jù)庫(kù)要使用新程序的時(shí)候,數(shù)據(jù)庫(kù)的升級(jí)簡(jiǎn)直就是無(wú)從下手.所以對(duì)比數(shù)據(jù)庫(kù)升級(jí)的緊要性就逐漸的凸現(xiàn)出來(lái).對(duì)于表和字段的升級(jí)按道理來(lái)說(shuō)是不難的,通過(guò)sysobjects與syscolumns的比較很容易的可以找到不同之處,然后增加沒(méi)有的對(duì)象即可.而對(duì)于視圖和存儲(chǔ)過(guò)程等非表對(duì)象的更新就有些為難了(當(dāng)然視圖和存儲(chǔ)過(guò)程如果用手工的辦法是很簡(jiǎn)單的).一個(gè)在于如何生成對(duì)象腳本,另一個(gè)在于如何執(zhí)行.大家都知道syscomments表中藏有此類對(duì)象的腳本,人們肯定會(huì)優(yōu)先考慮開(kāi)采這個(gè)寶庫(kù).當(dāng)站在字符型變量最大只能存儲(chǔ)8000個(gè)字符時(shí),這簡(jiǎn)直就是一個(gè)不可逾越的障礙.人們又想從導(dǎo)出文本腳本然后執(zhí)行這個(gè)思路著手時(shí),又發(fā)現(xiàn)從字段中取出的腳本有個(gè)天然的缺陷:換行問(wèn)題.(最后發(fā)現(xiàn),這個(gè)問(wèn)題也是可以解決的).萬(wàn)般無(wú)奈下人們把渴望的目光集中到了SQLDMO上,她的身上總散發(fā)著無(wú)所不能的光芒.
當(dāng)Transfer對(duì)象的美妙身材展現(xiàn)在人們眼前的時(shí)候,大家都對(duì)她的美麗所折服——這不正是我們所尋找的嗎?她的動(dòng)人之處就在于可以把一個(gè)數(shù)據(jù)庫(kù)的對(duì)象腳本保存在內(nèi)存中,然后連接到另一個(gè)數(shù)據(jù)庫(kù)上執(zhí)行.太棒了!現(xiàn)在我們來(lái)看看她的輪廓吧:
重要屬性:
CopyAllDefaults Boolean;;所有默認(rèn)值
CopyAllObjects; Boolean;;所有對(duì)象
CopyAllRules;;Boolean;;所有規(guī)則
CopyAllStoredProceduresBoolean;所有存儲(chǔ)過(guò)程
CopyAllTables;Boolean;;所有表
CopyAllTriggers Boolean;;所有觸發(fā)器
CopyAllUserDefinedDatatypes;;;Boolean;;;;所有用戶自定義類型
CopyAllViews;;Boolean;;所有視圖
CopyDataBoolean;;所有數(shù)據(jù)
DestDatabase;String;;;;目標(biāo)對(duì)象數(shù)據(jù)庫(kù)
DestLogin; String;;;;目標(biāo)數(shù)據(jù)庫(kù)登陸用戶名
DestPassword;;String;;;;目標(biāo)數(shù)據(jù)庫(kù)登陸密碼
DestServer String;;;;目標(biāo)服務(wù)器
DestUseTrustedConnection; Boolean; 用戶信任連接
DropDestObjectsFirst; Boolean;;是否先刪除目標(biāo)對(duì)象
IncludeDependenciesBoolean;;是否包含依靠對(duì)象
ScriptType; Boolean;;腳本類型
重要方法:
AddObject增加對(duì)象
AddObjectByName;通過(guò)對(duì)象名稱增加對(duì)象
好了,大家應(yīng)該對(duì)這個(gè)對(duì)象略有些了解了.對(duì)SQLDMO熟悉的人也許一下子就可以從中得到靈感,而初學(xué)者在這里恐怕還是一頭霧水.不過(guò)不用著急,具體用法我們會(huì)慢慢道來(lái):
CREATE PROCEDURE; P_UDB --以源數(shù)據(jù)庫(kù)為模板升級(jí)目標(biāo)數(shù)據(jù)庫(kù)
(; @Source_DB; sysname;;--原數(shù)據(jù)庫(kù)
,@Des_DB;;sysname;;--目標(biāo)數(shù)據(jù)庫(kù)
,@UserNamesysname;;--用戶名
,@psw;;;;;sysname;;--密碼
)
AS
set nocount on
--/*; 局部變量聲明
declare; @ObjName;;;sysname
,@SrvID;int;;--服務(wù)器ID
,@DBsId;int;;--數(shù)據(jù)庫(kù)集ID
,@transferID;;;int;;--傳輸ID
,@SDBId;int;;--源數(shù)據(jù)庫(kù)ID
,@DDBID;int;;--目標(biāo)數(shù)據(jù)庫(kù)ID
,@SViewListID;;int;;--源數(shù)據(jù)庫(kù)視圖列表;
,@DViewListID;;int;;--目標(biāo)數(shù)據(jù)庫(kù)視圖列表;
,@str;;;Nvarhar(4000)
,@name;;sysname
,@hr;;;;int;--執(zhí)行語(yǔ)句返回值
,@Errorint;;;;--錯(cuò)誤返回值(999:存儲(chǔ)過(guò)程或觸發(fā)器錯(cuò)誤;9999:視圖錯(cuò)誤)
--*/;;
--/*創(chuàng)建sqldmo對(duì)象; 前面我們已經(jīng)說(shuō)過(guò)SQLDMO是個(gè)com,在SQL Server中使用OLE --自動(dòng)化對(duì)象需要用到sp_OACreate等一系列的存儲(chǔ)過(guò)程,讀者如果有不明白的可以自--己查閱相關(guān)資料
exec @hr=sp_oacreate 'SQLDMO.sqlserver',@SrvID output
if @hr<>0
begin
set @Error=1
goto PEnd
end
--*/
--/*連接服務(wù)器
exec @hr=sp_oamethod @SrvID,'connect',null,@@ServerName,@UserName,@psw
if @hr<>0
begin
set @Error=2
goto PEnd
end
--*/
--/*取數(shù)據(jù)庫(kù)集
exec @hr=sp_oagetproperty @SrvID,'databases',@DBsId output
--*/
--/*選擇源數(shù)據(jù)庫(kù);
exec @hr=sp_oamethod @DBsId,'item',@SDBId output,@Source_DB
if @hr<>0
begin
set @Error=3
goto PEnd
end
--*/
--/*選擇目標(biāo)數(shù)據(jù)庫(kù);
exec @hr=sp_oamethod @DBsId,'item',@DDBId output,@Des_DB
if @hr<>0
begin
set @Error=4
goto PEnd
end
--*/
/*Tansfer屬性設(shè)置(生成三大對(duì)象)
exec @hr=sp_oacreate 'SQLDMO.Transfer',@transferID output
exec @hr=sp_oasetproperty@transferID,'DestServer',@@ServerName
exec @hr=sp_oasetproperty@transferID,'DestLogin',@UserName
exec @hr=sp_oasetproperty@transferID,'DestPassword ',@psw
exec @hr=sp_oasetproperty@transferID,'DestDatabase',@des_DB
exec @hr=sp_oasetproperty@transferID,'DropDestObjectsFirst ',1
exec @hr=sp_oasetproperty@transferID,'CopyAllStoredProcedures ',1
exec @hr=sp_oasetproperty@transferID,'CopyAllTriggers',1
exec @hr=sp_oasetproperty@transferID,'CopyAllViews',1
--exec @hr=sp_oasetproperty@transferID,'ScriptType ',1 這里大家可以試試這個(gè)屬性
exec @hr=sp_oamethod; @DDBId,'Transfer ',null,@transferID
exec sp_OADestroy @TransferID;
if @hr<>0
begin
set @Error=10
goto PEnd
end
*/
PEnd:
exec @hr = sp_OAMethod @SrvID, 'DisConnect';
exec sp_OADestroy @SrvID;
print (@Error)
Return (@Error)
GO
上邊的存儲(chǔ)過(guò)程只要是介紹方法的實(shí)現(xiàn),而具體的功能比如表及字段的比較生成這里就省略了.
其實(shí)有一個(gè)大家最后也沒(méi)能解決好的問(wèn)題就是對(duì)象依賴的問(wèn)題.許多對(duì)象比如視圖里嵌視圖,這時(shí)生成與執(zhí)行需要有順序的.雖然有算法但有缺陷.希望讀者能可以提供好的算法.
