【问题标题】:Using Transaction使用事务
【发布时间】:2012-10-22 17:25:42
【问题描述】:

如何更改以下过程,如果由于 PrimaryKey 或其他原因未成功执行插入语句,则也不得执行 Delete 语句,而且它应该生成一条我自己编写的错误消息。

CREATE PROCEDURE [dbo].[ReAdmissionInsert]
@GRNo varchar(4),
@ClassId numeric(2),
@FacultyId numeric(1),
@Section varchar(1),
@SessionId numeric(1)
AS
begin
insert into ReAdmissionDtl(GRNo,ClassId,FacultyId,Section,SessionId) values(@GRNo,@ClassId,@FacultyId,@Section,@SessionId)
delete from Discharge where GRNo = @GRNo
end

【问题讨论】:

    标签: sql-server stored-procedures transactions try-catch


    【解决方案1】:

    您使用BEGIN TRANCOMMIT 创建一个事务,如果您的INSERTDELETE 失败,该事务将回滚:

    CREATE PROCEDURE [dbo].[Readmissioninsert] @GRNo      VARCHAR(4),
                                               @ClassId   NUMERIC(2),
                                               @FacultyId NUMERIC(1),
                                               @Section   VARCHAR(1),
                                               @SessionId NUMERIC(1)
    AS
      BEGIN
          BEGIN TRAN  --<= Starting point of transaction
    
          INSERT INTO readmissiondtl
                      (grno,
                       classid,
                       facultyid,
                       section,
                       sessionid)
          VALUES     (@GRNo,
                      @ClassId,
                      @FacultyId,
                      @Section,
                      @SessionId)
    
          DELETE FROM discharge
          WHERE  grno = @GRNo
    
          COMMIT --<= End point of transaction
      END 
    

    Documentation

    您可以使用TRY CATCH 作为错误消息:

    【讨论】:

    • 我已经应用了您的代码,但这不起作用。当我通过插入语句输入重复值时,它给出了违反主键的错误,而我的放电表中给定 GRNo 的记录尚未被删除
    • @kashif 我不明白为什么事务不会回滚。我已经提供了实现错误消息的资源。
    【解决方案2】:

    使用事务和 try catch 块。在 catch 块中提出错误,如下所示:

    CREATE PROCEDURE [dbo].[ReAdmissionInsert]
    @GRNo varchar(4),
    @ClassId numeric(2),
    @FacultyId numeric(1),
    @Section varchar(1),
    @SessionId numeric(1)
    AS
    begin
    Begin transaction
    Begin try
        insert into ReAdmissionDtl(GRNo,ClassId,FacultyId,Section,SessionId)
           values(@GRNo,@ClassId,@FacultyId,@Section,@SessionId)
        delete from Discharge where GRNo = @GRNo
        Commit transaction
    End try
    Begin catch
        Rollback
        Raiserror(999999,'my message',16,1)
    End catch
    end
    

    【讨论】:

    • 非常感谢它的工作...如何在错误消息中插入从表中选择的值。就像如果我想设置我的错误消息,比如“我的错误消息”+ 从 mytable 中选择 mycolumn,mycolumnvalue = 'myvalue' 现在假设如果选择的值是 myvalue,那么错误消息应该是这样的。 '我的错误信息 myvalue' 我不知道我是否明确了我想要的东西。但也许你明白我在说什么
    【解决方案3】:

    使用事务编写 SQL Server 存储过程的最佳实践 -

    1. TRY..CATCH块括起来
    2. 检查 @@TRANCOUNTROLLBACK 错误交易
    3. RAISE实际ERROR报警调用程序

    示例 -

    CREATE PROCEDURE [dbo].[ReAdmissionInsert]
    @GRNo varchar(4),
    @ClassId numeric(2),
    @FacultyId numeric(1),
    @Section varchar(1),
    @SessionId numeric(1)
    AS
    BEGIN
    SET NOCOUNT ON
    BEGIN TRY   
        BEGIN TRAN
    
        insert into ReAdmissionDtl(GRNo,ClassId,FacultyId,Section,SessionId)
           values(@GRNo,@ClassId,@FacultyId,@Section,@SessionId)
    
        delete from Discharge where GRNo = @GRNo
    
        COMMIT TRAN     
    END TRY    
    BEGIN CATCH
    
        IF @@TRANCOUNT > 0
            ROLLBACK TRAN
    
        /*ERROR OCCURED*/  
        DECLARE @ERROR_MESSAGE NVARCHAR(4000);--MESSAGE TEXT           
        DECLARE @ERROR_SEVERITY INT;--SEVERITY           
        DECLARE @ERROR_STATE INT;--STATE        
    
        SELECT @ERROR_MESSAGE = ERROR_MESSAGE(),        
            @ERROR_SEVERITY = ERROR_SEVERITY(),        
            @ERROR_STATE = ERROR_STATE() 
    
    
        /*RETURN ERROR INFORMATION ABOUT THE ORIGINAL ERROR THAT CAUSED
          EXECUTION TO JUMP TO THE CATCH BLOCK.*/           
        RAISERROR (@ERROR_MESSAGE, @ERROR_SEVERITY, @ERROR_STATE)
    
    END CATCH   
    END
    

    请注意,检查 @@TRANCOUNT 以验证是否有任何打开的事务,并保留并引发 ERROR 消息,因此程序将收到 SqlException

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-07
      • 2014-02-05
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 2015-09-30
      • 2011-12-10
      • 1970-01-01
      相关资源
      最近更新 更多