sql在具有回滚的事务中多次插入

时间:2014-01-13 12:03:05

标签: sql-server sql-server-2008 tsql

我执行时有一个存储过程,它会在两个表中插入几条记录。

让我们说在作者表中插入一条记录并在书表中插入几条记录(作者的书籍)。

如何使用回滚在事务中插入所有内容?

我读了一些文章/博客,@@ 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

4 个答案:

答案 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