|
我們都知道,在紫金橋軟件中可以通過腳本或報表來訪問關係庫係統。我們通常的訪問方式大概如下(以報表訪問關係庫為例):
- 建立報表關係數據源點,配置關係數據源點連接的數據庫用戶名和密碼等屬性。
- 繪製報表,在報表的關係數據庫連接中指明第一步建立的報表關係數據源點。
- 在報表上寫對關係庫操作的命令,比如SELECT命令。
- 在報表中對關係庫返回的結果進行處理,最簡單的是報表自動顯示結果。
這裏第3步的SELECT命令中可以訪問SQL中的表或視圖。另外也可以使用存儲過程,比如:
#R.SqlExeCmdNoRet("EXEC DOTRANCDATA");
這裏的EXEC DOTRANCDATA表示執行DOTRANCDATA這個存儲過程。
下麵我們通過一個簡單的例子來說明一下存儲過程的用法。
biruwomenxuyaozuoyigechanpinchurukudexiangmu,chanpinzaimouyigedifangtongguoqudonghuotiaomashebeizidongjinxingrukucaozuo,dangshujujinruguanxikuzhihou,keyitongguoguanxikudegezhongtongjifenxizhaxungongnenglaiduichanpinjinxingtongjihejiansuo,youyuxuyaozaiduogedifangjinxingjiansuo,suoyiSQL數據庫放在遠端網絡的一個服務器上。
danshizhelicunzaizhemeyigewenti,youyuwangluoyoukenenghuiouerchuxianguzhang,suiranzaiguzhangqingkuangxiazanshibunengzhaxunshikeyilijiede,danshiwomenbunengyunxuzaiwangluochuxianguzhangdeqingkuangxia,chanpinbunengruku。
zhezhongwentikeyizhemejiejue,zaibendiguanxikuzhongjianliyigehuanchongbiao,shujuxiancharubendidehuanchongbiaozhong,ranhoutongguocunchuguocheng,babendidehuanchongbiaozhongdeshujuyidongdaoyuanduandechanpinkuzhong。zaibendiderenhejiansuohezhaxundoushizhenduideyuanduandechanpinkulaijinxing。zheyangdangwangluozhongduandeshihou,shujujiukeyixianhuanchongdaobendi,cishichanpinderukugongzuorengrankeyishunlidejinxing,zhibuguobendideshujuwufazidongdeyidongdaoyuanduan,cishizaiyuanduandeshujukuzhongshiwufajiansuodaozhexierukudechanpinde。dangwangluohuifuzhihou,youcunchuguochengzidongdebashujuyidongdaoyuanduanshujukuzhong,cishizaiyuanduanshujukuzhongjiukeyijiansuodaozhexiechanpinle。
下xia麵mian我wo們men舉ju一yi個ge簡jian單dan的de例li子zi,為wei了le簡jian化hua說shuo明ming我wo們men的de兩liang個ge表biao都dou在zai本ben地di數shu據ju庫ku中zhong,首shou先xian數shu據ju插cha入ru其qi中zhong的de一yi個ge表biao中zhong,然ran後hou在zai使shi用yong存cun儲chu過guo程cheng移yi動dong到dao另ling外wai一yi個ge表biao。對dui於yu跨kua數shu據ju庫ku的de表biao,處chu理li方fang式shi一yi樣yang,隻zhi需xu要yao稍shao微wei做zuo些xie調tiao整zheng就jiu行xing了le。
首先我們在SQL中建立兩個表,名為“測試數據源”和“測試目標”,如下圖所示:

在測試數據源和測試目標中建立結構相同的兩個數據表,如下圖所示:

這裏是一個簡單的人員入庫表,表明為User,有三個字段,第一個是自動增長的ID,第二個是人名,第三個年齡。
我們在紫金橋中創建一個關係數據源點,讓該點連接“測試數據源”數據庫,如下圖所示:

在紫金橋中創建一個窗口,並且創建一個報表,給報表關聯剛剛建立的報表關係數據源點。
在報表上允許用戶輸入姓名和年齡,如下圖所示:

給姓名和年齡的輸入位置設置相應的輸入方式,給提交按鈕關聯如下的腳本:
SqlExeCmdNoRet("INSERT INTO [User](Name, [Year]) VALUES ('"+Txt(1,1)+"', "+Txt(2,1)+")");
即可把人員姓名和年齡插入數據庫中。
下麵我們通過存儲過程來把數據從“測試數據源”庫移動到“測試目標”庫中。
在“測試數據源”庫中創建一個存儲過程,如下圖所示:

點擊確定即可創建存儲過程。
打開SQL查詢分析器,選中相應的存儲過程,右鍵菜單選擇編輯功能,如下圖所示:

在此處輸入如下的代碼:
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS OFF
GO
ALTERPROCEDURE MoveDataAS
DECLARE @strVARCHAR(1000)
DECLARE @SqlstrVARCHAR(1000)
SET @str = ''
SELECT @str=@str+','+syscolumns.[name] FROM syscolumns WHERE syscolumns.id=object_id('User') and syscolumns.[name]<>'ID'
SET @str = stuff(@str,1,1,'')
SET @str = 'INSERT INTO 測試目標.dbo.[User](' + @str + ') SELECT ' + @str + ' FROM 測試數據源.dbo.[User]'
DECLARE Ptr CURSOR
FOR
SELECT ID FROM 測試數據源.dbo.[User]
OPEN Ptr
DECLARE @ID INT
FETCH NEXT FROM Ptr INTO @ID
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
BEGIN
SET @Sqlstr = @str + ' WHERE ID=' + CONVERT(varchar, @ID)
EXEC(@Sqlstr)
DELETE FROM 測試數據源.dbo.[User] WHERE ID = @ID
END
FETCH NEXT FROM Ptr INTO @ID
END
CLOSE Ptr
DEALLOCATE Ptr
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
其中前麵和後麵5行代碼,是固定的,功能主要是更改存儲過程的內容。
中間的內容是移動數據,這裏我們不能簡單的這樣寫:
INSERT INTO 測試目標.dbo.[User] SELECT * FROM 測試數據源.dbo.[User]
因為,兩個表中都有自動增長的字段ID,如果複製所有的內容,也會導致複製ID字段的內容,而這會打亂係統自動增長的規律,可能會導致執行失敗。
DECLARE @strVARCHAR(1000)
DECLARE @SqlstrVARCHAR(1000)
SET @str = ''
SELECT @str=@str+','+syscolumns.[name] FROM syscolumns WHERE syscolumns.id=object_id('User') and syscolumns.[name]<>'ID'
SET @str = stuff(@str,1,1,'')
這一段代碼,查詢User表中的所有名稱不為ID的字段的名稱,並用逗號分隔。
SET @str = stuff(@str,1,1,'')
這一句代碼的功能是去除開始的逗號。
SET @str = 'INSERT INTO 測試目標.dbo.[User](' + @str + ') SELECT ' + @str + ' FROM 測試數據源.dbo.[User]'
這一句代碼生成複製數據的命令。
DECLARE Ptr CURSOR
FOR
SELECT ID FROM 測試數據源.dbo.[User]
OPEN Ptr
DECLARE @ID INT
FETCH NEXT FROM Ptr INTO @ID
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
BEGIN
SET @Sqlstr = @str + ' WHERE ID=' + CONVERT(varchar, @ID)
EXEC(@Sqlstr)
DELETE FROM 測試數據源.dbo.[User] WHERE ID = @ID
END
FETCH NEXT FROM Ptr INTO @ID
END
CLOSE Ptr
DEALLOCATE Ptr
這一段代碼,使用了多個遊標,逐行的複製數據和刪除數據,以實現移動數據的目的。
這(zhe)裏(li)之(zhi)所(suo)以(yi)采(cai)取(qu)一(yi)行(xing)一(yi)行(xing)的(de)移(yi)動(dong)數(shu)據(ju),主(zhu)要(yao)是(shi)為(wei)了(le)防(fang)止(zhi),在(zai)移(yi)動(dong)數(shu)據(ju)的(de)過(guo)程(cheng)中(zhong),又(you)有(you)了(le)新(xin)的(de)人(ren)員(yuan)入(ru)庫(ku),插(cha)入(ru)了(le)新(xin)的(de)記(ji)錄(lu)。一(yi)行(xing)一(yi)行(xing)的(de)移(yi)動(dong)可(ke)以(yi)使(shi)得(de)複(fu)製(zhi)數(shu)據(ju)和(he)刪(shan)除(chu)數(shu)據(ju)可(ke)以(yi)一(yi)一(yi)對(dui)應(ying)。
最後可以把此存儲過程放到作業中,使得它可以被周期運行,就可以實現自動的數據移動了。
|