sql server 存储过程中使用事务

 

 

一、存储过程中使用事简单语

      在存储过程中使用事务时非常重要的,使用数据可以保持数据的关联完整性,在Sql server储过程中使用事也很简单,用一个例子来明它的法格式:

 

    Create Procedure  MyProcedure    (   @Param1       nvarchar(10),       @param2    nvarchar(10)    )    AS       Begin           Set    NOCOUNT    ON;           Set XACT_ABORT ON;           Begin  Tran              Delete from       table1 where name=’abc’;              Insert into       table2 values(value1,value2,value3);           Commit Tran       End

 

 

      明:、使用存储过行事物,需要XACT_ABORT参数(认值为Off),将参数On,表示当行事务时,如果出,会将transcationuncommittable,那束后将回所有操作;如果参数Off,表示当行事务时,如果出,出句将不会行,其他正确的操作继续执行。

2、当SET NOCOUNT  ON ,不返回数(数表示受 Transact-SQL 句影响的行数,例如在Sql server查询分析器中行一个delete操作后,下方窗口会提示(3Rows Affected)。当   SET NOCOUNT  OFF ,返回,们应该在存储过程的部加上SET NOCOUNT ON 这样,在退出存储过程的候加上 SET NOCOUNT OFF这样,以达到化存储过程的目的。

 

 

 

 

二、事置保存点

  可以在事置保存点或标记。保存点定如果有条件地取消事的一部分,事可以返回的位置。如果将事到保存点,(如果需要,使用更多的 Transact-SQL 句和 COMMIT TRANSACTION 句)继续完成事,或者必(通将事到其起始点)完全取消事。若要取消整个事使用 ROLLBACK TRANSACTION transaction_name 格式。将撤消事的所有句和程。

如:

Create Procedure  MyProcedureAS    Begin           Set    NOCOUNT    ON;           Set XACT_ABORT ON;           begin   tran  ok  --始一个事OK               delete  from  rxqz  where qz=   'rx015 ' --除数据             save   tran  bcd   --保存一个事点命名bcd              update  sz  set   name='s' where name= ''--修改数据            if  @@error<>0  --判断修改数据有没有出                   begin --如果出                        rollback   tran  bcd  -- BCD 原点                    commit   tran  ok  --提交事                     end               else  --没有出                commit  tran ok --提交事       End

 

 

  明:1@@error判断是否有错误0表示没有错误,但是重大错误无法捕捉,而且@@error只能前一句sql句生效。

 

 

 

 

 

 

三、存储过程使用try…catch获错误

  在存储过程中可以使用try…catch句来捕获错误,如下:  

Create Procedure  MyProcedure    (   @Param1       nvarchar(10),       @param2    nvarchar(10)    )    AS       Begin           Set    NOCOUNT    ON;           Begin  try              Delete from       table1 where name=’abc’;              Insert into       table2 values(value1,value2,value3);           End    try           Begin  Catch                  SELECT ERROR_NUMBER()  AS  ErrorNumber,                       ERROR_MESSAGE()  AS  ErrorMessage;           End    Catch    End

 

 

  明:1、捕获错误的函数有很多,如下:

           ERROR_NUMBER() 返回错误号。

    ERROR_SEVERITY() 返回重性。

    ERROR_STATE() 返回错误号。

    ERROR_PROCEDURE() 返回出现错误的存储过程或触器的名称。

    ERROR_LINE() 返回错误的例程中的行号。

    ERROR_MESSAGE() 返回错误消息的完整文本。文本可包括任何可替参数所提供的,如度、象名或时间

    2、有些错误,如sql句中的表名称错误是数据引擎无法解析个表名称,所生的错误在当前的try…catch句中无法捕,必由外层调储过程的地方使try…catch行捕

 

 

 

 

四、存储过程中事try…catch合使用

  在存储过程中使用事务时,如果没有try…catch句,那set xact_abort on,如果有错误发生,在批束后,系会自所有的sql操作。当set xact_abort off,如果有错误发生,在批束后,系行所有没有错误句,错误句将不会被行。

在存储过程中使用事务时,如果存在try…catch,那当捕错误时,需要在catch中手动进Rollback操作,否传递一条错误信息。如果在存储过set xact_abort on,那当有错误发,系会将当前事可提交状,即会将xact_state()-1,此只可以务进Rollback操作,不可行提交(commit)操作,那catch中就可以根据xact_state()来判断是否有事务处于不可提交状,如果有可以rollback操作了。如果在存储过set xact_abort off,那当有错误发,系不会xact_state()-1,那catch中就不可以根据函数来判断是否需要rollback了,但是我可以根据@@Trancount全局量来判断,如果在catch中判断出@@Trancount大于0,代表有未提交的事,既然catch了,那么还存在未提交的事务应该是需要rollback的,但是这种方法在某些情况下可能判断的不准确。推荐的方法是将set xact_abort on,然后在catch中判断xact_state()来判断是否需要Rollback操作。

下面我来看看两个例子:

一.使用Set xact_abort       on

Create  proc  myProcedureAs    begin       set xact_abort on;       begin try           begin tran              insert into TestStu values('Terry','boy',23);              insert into TestStu values('Mary','girl',21);           commit tran       end try       begin catch

           --在此可以使用xact_state()来判断是否有不可提交的事,不可提交的事           --表示在事内部错误了。Xact_state()有三种值-1.不可提交;           --1.可提交;0.表示没有事,此commit或者rollback报错           if xact_state()=-1              rollback tran;       end catchend

 

 

 .使用Set xact_abort off

 

Create  proc  myProcedureAs    begin      set xact_abort off;       begin try           begin tran              insert into TestStu values('Terry','boy',23);              insert into TestStu values('Mary','girl',21);           commit tran       end try       begin catch           --在此不可以使用xact_state来判断是否有不可提交的事           --只可以使用@@Trancount来判断是否有未提交的事,未提交的事未必           --就是不可提交的事,所以使用@@TranCount>0后就RollBack是不准确的           if @@TranCount>0              rollback tran;       end catchend

 

 

     另外,@@Trancount需要明的是,begin  tran 句将 @@Trancount加 1Rollback  tran将 @@Trancount减到 0,但 Rollback tran savepoint_name 除外,它不影响 @@TrancountCommit  tran 或 Commit  work 将 @@Trancount  1

 

posted on 2012-07-05 11:48  雨婷听雨  阅读(791)  评论(0编辑  收藏  举报

导航