我执行时有一个存储过程,它会在两个表中插入几条记录。
让我们说在作者表中插入一条记录并在书表中插入几条记录(作者的书籍)。
如何使用回滚在事务中插入所有内容?
我读了一些文章/博客,@@ trancount / @@ error / XACT_STATE()让我感到困惑。
什么是最好的方法?
这是我的过程:
CREATE PROCEDURE [dbo].[proc_addAuthors]
@bookid1 int, @bookid2 int, @bookid3 int, @bookid4 int, @bookid5 int,
@authInfo
AS
insert into author...(leave out params)
--get authorId
...
--insert books (leave out validation checks...)
insert into author2book(authorId, bookId) values(@authorid, @bookid1)
...
RETURN 0
答案 0 :(得分:0)
如果您只是想确保插件成功完成,或者两者都在发生错误时回滚,则需要将以下内容添加到存储过程中:
CREATE PROCEDURE [dbo].[proc_addAuthors]
@bookid1 int, @bookid2 int, @bookid3 int, @bookid4 int, @bookid5 int,
@authInfo
AS
SET XACT_ABORT ON; -- Automatically rollback if an error occurs.
BEGIN TRANSACTION;
insert into author...(leave out params)
--get authorId
...
--insert books (leave out validation checks...)
insert into author2book(authorId, bookId) values(@authorid, @bookid1)
...
COMMIT TRANSACTION;
RETURN 0
答案 1 :(得分:0)
CREATE PROCEDURE addTitle(@title_id VARCHAR(6), @au_id VARCHAR(11),
@title VARCHAR(20), @title_type CHAR(12))
AS
BEGIN TRAN
INSERT titles(title_id, title, type)
VALUES (@title_id, @title, @title_type)
IF (@@ERROR <> 0) GOTO ERR_HANDLER
INSERT titleauthor(au_id, title_id)
VALUES (@au_id, @title_id)
IF (@@ERROR <> 0) GOTO ERR_HANDLER
COMMIT TRAN
RETURN 0
ERR_HANDLER:
PRINT 'Unexpected error occurred!'
ROLLBACK TRAN
RETURN 1
答案 2 :(得分:0)
以下是使用现代TRY CATCH块来测试错误的方法
CREATE PROCEDURE [dbo].[proc_addAuthors]
@bookid1 int, @bookid2 int, @bookid3 int, @bookid4 int, @bookid5 int,
@authInfo
AS
BEGIN TRY
BEGIN TRANSACTION
insert into author...(leave out params)
--get authorId
...
--insert books (leave out validation checks...)
insert into author2book(authorId, bookId) values(@authorid, @bookid1)
...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() as errorMessage -- for example
ROLLBACK
RETURN 1 -- for example
END CATCH
RETURN 0
答案 3 :(得分:0)
使用Try..Catch块可以访问错误函数,您可以使用它来获取有关错误的详细信息。
CREATE PROCEDURE [dbo].[proc_addAuthors]
@bookid1 int, @bookid2 int, @bookid3 int, @bookid4 int, @bookid5 int,
@authInfo
AS
BEGIN
SET NOCOUNT ON;
DECLARE @NewAuthorID INT;
BEGIN TRY
BEGIN TRANSACTION
insert into author...(leave out params)
--get authorId
SET @NewAuthorID = SCOPE_IDENTITY(); --<-- Get new AuthorID generated by Identity column
--insert books (leave out validation checks...)
insert into author2book(authorId, bookId) --<-- use that NewAuthorID param here
values(@NewAuthorID, @bookid1)
...
COMMIT TRANSACTION
RETURN 0
END TRY
BEGIN CATCH
IF (@@TRANCOUNT > 0)
ROLLBACK TRANSACTION
DECLARE @ErrorNum int
SELECT @ErrorNum = ERROR_NUMBER()
SELECT ERROR_MESSAGE() AS ErrorMessage,
ERROR_LINE() AS ErrorLine,
--<--.... ( Other Error Functions )
RETURN @ErrorNum
END CATCH
END