存儲過程即為能完成特定功能的一組SQL語句集。如果需要對查出的多條數(shù)據(jù)進行操作的話,這里需要理解游標(CURSOR)的概念,對于oracle有for each row命令,可以不用游標。
游標可以理解為一個結(jié)果集,描述cursor的關(guān)鍵字有:
SCROLL關(guān)鍵字指明游標可以在任意方向上滾動
FORWARD_ONLY指明游標只能向前滾動。
READ ONLY指明在游標結(jié)果集中不允許進行數(shù)據(jù)修改。
UPDATE關(guān)鍵字指明游標的結(jié)果集可以修改。
GLOBAL關(guān)鍵字使得游標對于整個連接全局可見
LOCAL關(guān)鍵字指明游標是局部的,它只能在它所聲明的過程中使用。
等等。。。
一般結(jié)果集需要遍歷,如例,將一些表中的字段查出來,插入到另外一張表中:
例1:查詢表數(shù)據(jù)插入到另外一張表
CREATE?PROCEDURE?sp_insertIntoTest_hibernate
AS
DECLARE?@projectid?VARCHAR(20)
DECLARE?@projectcode?VARCHAR(20)
DECLARE?@projectname?VARCHAR(100)
DECLARE?@projectamount?DECIMAL(16,2)
DECLARE?@remark?VARCHAR(1000)
DECLARE?cs?CURSOR?FOR?--定義游標的數(shù)據(jù)集
SELECT?L.PROJECTID,P.CODE,L.PROJECTNAME,L.LEASINGAMOUNT, L.proInfoSummary
FROM?LAPROJECT L?LEFT?JOIN?PARTY_CUSTOMER P?ON?P.ID=L.TENANTID
WHERE?(L.TENANTID<>''?AND?L.TENANTID?IS?NOT?NULL)?ORDER?BY?L.PROJECTID
BEGIN
DELETE?FROM?test_hibernate
OPEN?cs?--打開游標
FETCH?NEXT?FROM?cs?INTO?@projectid,@projectcode,@projectname,@projectamount,@remark?--從游標中取值賦給變量
????WHILE @@FETCH_STATUS = 0?--fetch語句執(zhí)行成功返回0,fetch語句執(zhí)行失敗或者此行不在結(jié)果集中返回-1,被提取的行不存在則返回-2.
????????BEGIN
????????PRINT?'====start insert===='
????????INSERT?INTO?test_hibernate?VALUES(@projectid,@projectcode,@projectname,@projectamount,@remark)
????????PRINT?'==== end? insert===='
????????FETCH?NEXT?FROM?cs?INTO?@projectid,@projectcode,@projectname,@projectamount,@remark?--繼續(xù)取下一行數(shù)據(jù)
????????END
????CLOSE?cs?--關(guān)閉游標
????DEALLOCATE?cs?--刪除游標
END
這個sp起初運行的時候老是報游標已存在問題,時不時還報游標不存在,郁悶。后來修改了下存儲過程換了個游標名稱就好了,網(wǎng)上查了很多說是游標沒關(guān)閉沒釋放或者是關(guān)閉釋放位置不對等問題,自己實踐證明我的問題不是這樣的,至今搞不懂是啥原因造成的問題,可能是第一次寫sp的時候沒釋放,后面加上了釋放和刪除那兩句話吧。
例2:分頁查詢
CREATE?PROCEDURE?sp_getpermbal?
@pageSize?INT,
@page?INT
AS
DECLARE?@temp?INT?SET?@temp=@pageSize*(@page-1)
BEGIN
SELECT?TOP?(SELECT?@pageSize) *?FROM?LAPERMBAL
WHERE?projectid+contractid+grantid+convert(varchar(20),retsn)+convert(varchar(10),ratebtdt,120)?NOT?IN
(SELECT?TOP?(SELECT?@temp) projectid+contractid+grantid+convert(varchar(20),retsn)+convert(varchar(10),ratebtdt,120)
FROM?LAPERMBAL?ORDER?BY?projectid,contractid,grantid,retsn,ratebtdt?DESC)
ORDER?BY?projectid,contractid,grantid,retsn,ratebtdt?DESC
END
這個查數(shù)據(jù)需要用到主鍵,而本例的表使用聯(lián)合主鍵,所以進行拼接來識別一條數(shù)據(jù)的唯一性。
二、觸發(fā)器(SQLServer)
觸發(fā)器都說是一種特殊的存儲過程,那我也就這么理解了,還挺有道理的、讓人比較容易接受的解釋。在數(shù)據(jù)庫的表數(shù)據(jù)有增、刪、改的操作時可自動觸發(fā)的存儲過程。
首先理解inserted和deleted兩張?zhí)摫?,看了下oracle相關(guān)的內(nèi)容,應(yīng)該是用new和old兩張?zhí)摫?,取值可用new.字段名,old.字段名。
新增操作新增的記錄存到系統(tǒng)建的虛表inserted中,deleted表無記錄;
刪除操作刪除的記錄存到系統(tǒng)建的虛表deleted中,inserted表無記錄;
修改操作(分解為先刪除再插入)刪除的記錄存到系統(tǒng)建的虛表deleted中,新增的記錄存到inserted表中。
然后就是觸發(fā)器類型,after觸發(fā)器和instead of 觸發(fā)器,這個不理解的可以百度,有很多比我解釋的更清楚的大神寫的文章。
理解完之后,記錄下相關(guān)語法:
新建觸發(fā)器:
例:更新test_hibernate表,則將被更新記錄的字段值置為“test success---”?
CREATE?TRIGGER?test_trigger
ON?test_hibernate
FOR?UPDATE
AS
DECLARE?@projectid?VARCHAR(20),@projectcode?VARCHAR(20)
DECLARE?cs?CURSOR?local?FOR
SELECT?projectid,projectcode?FROM?deleted
BEGIN
OPEN?cs
FETCH?NEXT?FROM?cs?INTO?@projectid,@projectcode
WHILE @@FETCH_STATUS=0
BEGIN
UPDATE?test_hibernate?SET?remark='test success---'?WHERE?projectid=@projectid?AND?projectcode=@projectcode
FETCH?NEXT?FROM?cs?INTO?@projectid,@projectcode
END
CLOSE?cs
DEALLOCATE?cs
END
GO
修改觸發(fā)器:
ALTER?TRIGGER?test_trigger?
ON?test_hibernate
FOR?UPDATE
AS?
......
禁用、啟用觸發(fā)器:
ALTER?TABLE?test_hibernate DISABLE?TRIGGER?test_trigger
ALTER?TABLE?test_hibernate ENABLE?TRIGGER?test_trigger
ALTER?TABLE?test_hibernate DISABLE?TRIGGER?ALL
ALTER?TABLE?test_hibernate ENABLE?TRIGGER?ALL
http://www.cnblogs.com/hoojo/archive/2011/07/20/2111316.html【轉(zhuǎn)載】