在論壇中出現的比較難的sql問題:20(觸發器專題2)

來源:互聯網
上載者:User

其中“執行其餘的語句不會激發嵌套觸發器”,是否意味著在復原操作後面的語句如果繼續執行的話,後面語句觸發的觸發器就不會執行了。比如後面的語句有針對一個表的update操作,而這張表又有update的觸發器,這個時候update會執行成功,但觸發器不會執行?


從下面的insert時的輸出,可以看出,在觸發器中rollback之後的語句,是可以執行的,另外,update另一個表的操作也執行成功,並且觸發了觸發器。


--drop table t1--drop table t2create table t1(id int)create table t2(id int)insert into t2values(100)gocreate trigger dbo.trigger_t1on t1for insertasrollback;select '這是rollback之後的語句,這裡能執行'update t2set id = 1;gocreate trigger dbo.trigger_t2on t2for updateasselect '這是t2的update觸發器,這裡能執行'go--插入資料insert into t1values(1)/*這是rollback之後的語句,這裡能執行這是t2的update觸發器,這裡能執行訊息 3609,層級 16,狀態 1,第 3 行事務在觸發器中結束。批處理已中止。*/ --沒有記錄select * from t1select * from t2/*id1*/


我在A表寫了個觸發器 插入後執行,是向B表插入一條記錄

USE [test]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER TRIGGER [dbo].[tba_delete]    ON  [dbo].[tba]    AFTER INSERTAS BEGINSET NOCOUNT ON;insert into test.dbo.tbb(title,info) values('title','info');END

在A表插入資料後正常。當我把 語言改為:

insert into test.dbo.tbb(id,title,info) values(1,'title','info');

故意出錯。問題出現了,當觸發器內的語句出錯,向A表插入的資料就不能成功插入。
向朋友們求教個問題。我要如何把觸發器中的出錯資訊記錄下來?或者在什麼地方可以查看到觸發器執行時是否出錯了,及查看錯誤的資訊?

USE [test]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOcreate table [tba](title varchar(20),info varchar(20))create table tbb(title varchar(20),info varchar(20))--建立一個存放錯誤資訊的表create table tb_error_message(obj_name nvarchar(30),obj_type nvarchar(15),err_msg nvarchar(100),err_date datetime)godrop trigger tba_deletegocreate TRIGGER [dbo].[tba_delete]    ON  [dbo].[tba]    AFTER INSERTAS BEGINSET NOCOUNT ON;begin try--這裡類比插入title列的資料長度,超過了定義時的20insert into test.dbo.tbb(title,info) values('title1111111111111111111','info');end trybegin catch--錯誤了就復原    rollback;insert into tb_error_messagevalues('tba_delete','trigger',error_message(),getdate())           end catchENDgoinsert into tbavalues('11','11')/*訊息 3930,層級 16,狀態 1,過程 tba_delete,第 16 行當前事務無法提交,而且無法支援寫入記錄檔的操作。請復原該事務。語句已終止。*/--查詢出錯的資訊select *from tb_error_message/*obj_nameobj_typeerr_msgerr_datetba_deletetrigger將截斷字串或位元據。2013-11-08 12:32:16.750*/

--先儲存一個事務點SAVEPOINT xxx begin try     --或者是調用預存程序,或者就直接寫代碼   exec 發送資訊的預存程序      end try  begin catch    select '執行失敗'    --一旦出錯,只是復原到上面的事務點,繼續執行  ROLLBACK [WORK] TO SAVEPOINT xxxend catch  --其他代碼



如何?AA表的欄位b(為整數型)中的資料 是BB表中的cc欄位(為整數型)所有資料記錄的總和(sum)!
要求做到BB表資料記錄增加的同時AA表中欄位b的記錄值自動同步更新。

對的,觸發器能實現你的需求,另外,索引能加快速度。因為這種同步的需求,首先,不是跨越伺服器的,一般跨越伺服器的,可以考慮用資料庫同步(非同步)、鏡像(同步)、記錄傳送(非同步)等技術。而你現在是在同一台伺服器上,要同步2個表的資料,所以用觸發器是最合適的,而且觸發器本身的特性是,在同一個事務中,只要你的資料插入成功,那麼另一個表的資料,也就是同步成功了,同樣的,如果插入失敗,報錯,那麼另一個表的資料也不會同步成功。再有,就是效率的問題,如果每次都sum求和,而你的表裡是上億的資料,這個sum肯定是非常耗時的,所以這裡採用的是,你插入1條資料,那麼只要把這個插入的資料,通過update 表 set c = c + 插入的值那麼自然就加快了速度,而且不會出現並發的問題。如果還想進一步加快速度,那麼可以考慮,給A表建立索引,因為a表肯定記錄也不會少,而且肯定是通過where條件來定義某一條記錄,然後update ,這個時候通過索引,就能更快的找到這條記錄,然後update。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.