1

我有两张桌子 -tblRequeststblData. tblRequests有一个名为 的主键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
4

1 回答 1

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
于 2013-03-29T17:33:45.933 回答