如何在SQL 2008中通过回滚设置try / catch块?

时间:2018-08-14 12:40:55

标签: sql-server sql-server-2008 stored-procedures transactions rollback

我在存储过程中有SQL事务,当客户尝试在Dictionary表中插入或更新记录时,该事务将每次运行。最初,我使用ColdFusion来处理事务和回滚,但是由于我移动了存储过程中的所有内容,因此现在需要SQL来处理。这是我的ColdFusion和SQL代码的示例:

<cftransaction action="begin">
    <cftry>
        <cfquery name="qrySave" datasource="#dsn#">
            UPDATE Dictionary WITH (serializable)
            SET Name = Name
            WHERE pk = @id
            IF @@rowcount = 0
            BEGIN
              INSERT Dictionary (pk, Name)
              VALUES (@id,1)
            END
        </cfquery>

        <cfset local.fnResults = {status : "200", RecID : qrySave.RecID}>

        <cfcatch type="any">
            <cftransaction action="rollback" />
            <cfset local.fnResults = {status : "400"}>
        </cfcatch>
    </cftry>
</cftransaction>

上面的示例应该进行修改,并使用SQL事务和回滚,到目前为止,我已经做到了:

begin tran
   update Dictionary with (serializable)
   set Name = Name
   where pk = @id
   if @@rowcount = 0
   begin
      insert Dictionary (pk, Name)
      values (@id,1)
   end
commit tran

我仍然需要回滚尝试/捕获,然后将其放入存储过程中。如果有人举了例子,请告诉我。

1 个答案:

答案 0 :(得分:1)

我同意@JeroenMostert关于理解您在做什么的评论,但我将以相同的起点为您提供我最喜欢的样板代码。

从SQL Server 2008开始,Try / Catch是有效的T-SQL,因此您很幸运,尽管您真的应该考虑尽快升级,因为2008年将在2019年7月退出扩展支持。

我通常的模式是启动事务,启动TRY块,如果代码成功则启动COMMIT或事件中ROLLBACK块中的CATCH故障,并返回有关该错误的一些信息。这是一个相当基本的实现。

BEGIN TRANSACTION
BEGIN TRY
  UPDATE
    Dictionary WITH (SERIALIZABLE)
  SET
    Name = Name
  WHERE
    pk = @id;
  IF @@rowcount = 0
    BEGIN;
      INSERT Dictionary (pk ,Name)
      VALUES (@id, 1);
    END;
  COMMIT TRANSACTION;
END TRY
BEGIN CATCH
  ROLLBACK TRANSACTION;
  SELECT -- As many or few of these as you care to return
    ERROR_NUMBER() AS ErrorNumber
   ,ERROR_SEVERITY() AS ErrorSeverity
   ,ERROR_STATE() AS ErrorState
   ,ERROR_PROCEDURE() AS ErrorProcedure
   ,ERROR_LINE() AS ErrorLine
   ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH