SQL脚本不会自动提交

时间:2015-05-06 04:47:53

标签: sql sql-server

只是想知道以下是否是编写使用BEGIN TRANSACTION的SQL脚本的正确方法? (像DML一样的东西)

BEGIN TRY
    BEGIN TRANSACTION
        /* SQL statements here */
    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    IF @@ERROR <> 0
    ROLLBACK TRANSACTION
END CATCH

每当我尝试在SQL服务器中执行它时,脚本都会运行但不知何故它不会提交事务。我仍然需要使用COMMIT TRANSACTION手动提交。

在我的SQL Server Management Studio 2012中,我检查了SET_IMPLICIT_TRANSACTIONS以避免在开发脚本时自动提交。但是因为如果所有语句都成功运行,我已经把语句COMMIT TRANSACTION放了,那么右边我的脚本应该自动提交吗?除非我在这里弄错了。

2 个答案:

答案 0 :(得分:1)

您的IF @@ERROR <> 0区块中不需要CATCH。当控制转移到CATCH块时,意味着发生了错误。你可以直接做这样的回滚

IF @@TRANCOUNT > 0 
ROLLBACK TRANSACTION

如果需要,您可以使用XACT_STATE()检查交易状态。

在catch块中,您可以在某些表中记录错误,或者根据您的要求和您正在使用的sql server版本,使用THROWRAISERROR来修复错误。

修改

当您IMPLICIT_TRANSACTIONS ON vs IMPLICIT_TRANSACTIONS OFF

时,存在差异

根据IMPLICIT_TRANSACTIONS ON的{​​{3}}:

  

当IMPLICIT_TRANSACTIONS = ON时,显式BEGIN TRANSACTION将启动两个嵌套事务。

脚本的测试表

CREATE TABLE test_table( a int)

使用SET IMPLICIT_TRANSACTIONS OFFSET IMPLICIT_TRANSACTIONS ON

运行相同的脚本
BEGIN TRANSACTION
SELECT @@TRANCOUNT
INSERT INTO test_table VALUES(1)
SELECT @@TRANCOUNT
COMMIT
SELECT @@TRANCOUNT
使用SET IMPLICIT_TRANSACTIONS OFF

输出

-----------
1
-----------
1
-----------
0
使用SET IMPLICIT_TRANSACTIONS ON

输出

-----------
2
-----------
2
-----------
1

因为当SET IMPLICIT_TRANSACTIONS ON有2个打开的事务而且只有一个提交时,似乎提交事务没有做任何事情。

有关错误处理的更多信息,请参阅以下参考链接:

答案 1 :(得分:0)

使用此代码:

BEGIN TRANSACTION
  BEGIN TRY
/* SQL statements here */
 COMMIT TRANSACTION
  END TRY
  BEGIN CATCH
ROLLBACK TRANSACTION
 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;
  END CATCH

因为你的Sql语句在里面运行 Begin..end try block:
1)如果没有错误发生,它会自动执行提交事务并退出尝试阻止
2)如果 TRY BLOCK 中的语句出错,它会直接跳转到 BEGIN CATCH 块,并使用 ROLLBACK TRANSACTION 放置那里的整个事务回滚在 CATCH BLOCK 中显示错误消息的类型。

使用此代码不需要手动提交事务。 如果没有错误,它会自动提交。