sql在具有回滚的事务中多次插入
Posted
技术标签:
【中文标题】sql在具有回滚的事务中多次插入【英文标题】:tsql mutiple inserts in a transaction with rollback 【发布时间】:2014-01-13 12:03:05 【问题描述】:我有一个存储过程,当执行它时,它会在 2 个表中插入几条记录。
假设在作者表中插入一条记录并在书籍表中插入几条记录(作者的书籍)。
如何在回滚事务中进行所有插入?
我读了一些文章/博客,@@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
【问题讨论】:
你的sql server是什么版本的? @rudibruchez 它在问题的标签中 - 2008。 【参考方案1】:如果您只想确保插入都成功完成,或者在发生错误时都回滚,则需要将以下内容添加到存储过程中:
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
【讨论】:
【参考方案2】: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
【讨论】:
【参考方案3】:这是使用现代 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
【讨论】:
【参考方案4】:使用 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
【讨论】:
@Scott 抱歉,您收到了什么错误消息??? n 是的,我错过了 ErrorNum 变量的数据类型,但您已经了解如何处理这种情况。以上是关于sql在具有回滚的事务中多次插入的主要内容,如果未能解决你的问题,请参考以下文章