我有两张桌子 - tblRequests
和tblData
。 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
答案 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