SQL Server 2005:尝试使用子表上的更新捕获

时间:2013-03-29 17:23:53

标签: sql-server-2005

我有两张桌子 - tblRequeststblDatatblRequests有一个名为recID的主键,tblData有一个指向该主键的外键,名为requestRecID

tblRequests上,我在两列上有一个唯一索引,可防止用户输入重复行。

问题:当我在tblRequests上尝试重复插入时,它会按预期出错,但我的tblData仍在更新其外键。

那么,如果tblData插入没有发生,我怎么说“不要更新tblRequests”?

在进行一些研究时,似乎try/catch是有序的,但我完全不熟悉这个级别的SQL。

我的代码如下:

CREATE Procedure [dbo].[spInsert]
(
    @vOpID varchar(3),
    @vSNumb varchar(12)
)
AS
    Declare @vRecID int
BEGIN 
    BEGIN TRANSACTION
        Insert tblRequests
        (
        opID,
        SNumb
        )
        Values 
        (
        @vOpID,
        @SNumb
        )

        Set @vRecID = IDENT_CURRENT ('tblRequests')

    COMMIT TRANSACTION;
    BEGIN TRANSACTION
        Update tblData 
        Set requestRecID = @vRecID 
        Where SNumb = @SNumb And opID = @vOpID 
    COMMIT TRANSACTION;
END

1 个答案:

答案 0 :(得分:2)

你需要这样的东西:

  • 一个事务跨越两个操作(因为您真的希望两个操作都成功,或者然后回滚所有内容 - 而不仅仅是事务的一部分......)

  • TRY...CATCH块内 - 如果第一个操作(INSERT)导致错误,它将直接跳转到CATCH块并且不会执行第二个语句,它将回滚交易。

代码:

CREATE Procedure [dbo].[spInsert]
(
    @vOpID varchar(3),
    @vSNumb varchar(12)
)
AS
BEGIN 
    DECLARE @vRecID INT

    BEGIN TRANSACTION
    BEGIN TRY
        INSERT INTO dbo.tblRequests(opID, SNumb)
        VALUES(@vOpID, @SNumb)

        SET @vRecID = SCOPE_IDENTITY()

        UPDATE dbo.tblData 
        SET requestRecID = @vRecID 
        WHERE SNumb = @SNumb AND opID = @vOpID 

        COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        SELECT 
            ERROR_NUMBER() AS ErrorNumber,
            ERROR_SEVERITY() AS ErrorSeverity,
            ERROR_STATE() AS ErrorState,
            ERROR_PROCEDURE() AS ErrorProcedure,
            ERROR_LINE() AS ErrorLine,
            ERROR_MESSAGE() AS ErrorMessage

        ROLLBACK TRANSACTION
    END CATCH
END