觸發器和儲存過程中錯誤處理

-----測試一  觸發器中的在什麼時候不放rollback
//表定義
CREATE TABLE [test] (
[test] [char] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [PK_test] PRIMARY KEY  CLUSTERED 
(
[test]
)  ON [PRIMARY] 
) ON [PRIMARY]
GO
CREATE TRIGGER tr_ins ON [dbo].[test] 
FOR INSERT
AS
rollback transaction
go


pb語句
string ls_code,ls_err
insert into test values('aa');
ls_code=string(sqlca.sqlcode)
ls_err=sqlca.sqlerrtext
if sqlca.sqlcode=0   then
commit;
else
rollback;
end if
messagebox(ls_code,ls_err)   //爲0
messagebox(string(sqlca.sqlcode),sqlca.sqlerrtext) 爲-1 commit沒有begin transaction

說明:1.觸發器中的rollbak tran 撤消語句的修改 直接將@@trancount=0,再執行commit就會出錯
   2.語句執行雖然被撤消,但沒有出錯,所以是成功執行.返回狀態爲0
觸發器改後:
CREATE TRIGGER tr_ins ON [dbo].[test] 
FOR INSERT
AS
raiserror('err ',16,1)
rollback transaction
結果爲    -1
          -1 rollback without begin transaction
最後正確的改法爲:如果是顯示的提交和撤消語句(應用程序中用如pb)
觸發器中應去掉 rollback語句,就由應用程序來撤消
結果爲    -1
          0
語句被正常處理,insert語句被撤消
--但是如果使用自動提交的將rollback去掉只保留raiserror,是不會回滾(使用自動提效時就將rollback加上)

CREATE PROCEDURE dt_test  AS
insert into test select '1'
insert into test values('2')
GO
insert into test values('1')
go
exec dt_test     
//存儲過程中第一條語句 insert into test select '1' 主鍵重複出錯,但並沒有終止,繼續執行下一條語句
這就造成事務的錯誤,(要麼全部修改,要麼全部不修改)
所以要在每條語句後面測試執行的結果 用@@error來測試
CREATE PROCEDURE dt_test  AS
begin tran t
insert into test select '1'
if @@error<>0
  goto fin
insert into test values('2')
if @@error<>0
  goto fin

commit tran t
return
fin:
 raiserror ('error',16,1)
 rollback tran t
GO






發佈了138 篇原創文章 · 獲贊 2 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章