存储过程中使用事务
一、存储过程中使用事简单语
      在存储过程中使用事务时非常重要的,使用数据可以保持数据的关联完整性,在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
 
 
      明:1 、使用存储过行事物,需要XACT_ABORT参数(默认值为Off),将参数On,表示当行事务时,如果出,会将transcationuncommittable状,那束后将回所有操作;如果参数Off,表示当行事务时,如果出,出句将不会行,其他正确的操作继续执行。
2、当SET NOCOUNT ON ,不返回数(数表示受 Transact-SQL 句影响的行数,例如在Sql server查询分析器中行一个delete操作后,下方窗口会提示(3)Rows Aff
ected)。当  SET NOCOUNT OFF ,返回,我们应该在存储过程的部加上SET NOCOUNT ON 这样,在退出存储过程的候加上 SET NOCOUNT OFF这样,以达到化存储过程的目的。
 
二、事置保存点
  可以在事置保存点或标记。保存点定如果有条件地取消事的一部分,事可以返回的位置。如果将事到保存点,(如果需要,使用更多的 Transact-SQL 句和 COMMIT TRANSACTION 句)继续完成事,或者必(通将事到其起始点)完全取消事。若要取消整个事使用 ROLLBACK TRANSACTION transaction_name 格式。将撤消事的所有句和程。
如:
Create Procedure  MyProcedure
AS
    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  myProcedure
As
    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 catch
end
 
 
 二.使用Set xact_abort off
 
Create  proc  myProcedure
As
    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来判断是否有未提交的事,未提交的事未必
try catch的使用方法          --就是不可提交的事,所以使用@@TranCount>0后就RollBack是不准确的
          if @@TranCount>0
              rollback tran;
      end catch
end

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。