Sql server SQL Server事务

Sql server SQL Server事务,sql-server,transactions,Sql Server,Transactions,我有两个sql server语句 Delete from hello where id=1 Insert into hello name,age select name ,age from welcome 如果其中一个失败,则不应执行删除或插入操作 我试过交易 Begin Tran Delete from hello where id=1 Insert into hello (name,age) select name ,age from welcome

我有两个sql server语句

Delete from hello where id=1

Insert into hello name,age 
select name ,age from welcome
如果其中一个失败,则不应执行删除或插入操作

我试过交易

Begin Tran

    Delete from hello where id=1

    Insert into hello (name,age) 
    select name ,age from welcome


Commit Tran
但如果其中一个出了问题,另一个犯了错,我是否错过了什么

2 delete statements

BEGIN TRY
    BEGIN TRAN;


  delete from hello where id=1

  delete from hello where id=19  // here id=19 doesn't exist

    COMMIT TRAN;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK;
    THROW;
END CATCH;
此处id=19不存在,因此它应该回滚,但它正在删除id=1。它是已提交的,而不是回滚。在此场景中我应该做什么

但如果其中一个出了错,另一个犯了错,我是不是失踪了 什么

是的,您缺少错误处理。根据错误的不同,T-SQL批处理可能会在错误后继续执行,并执行后续语句,包括commit。下面是避免这种情况的结构化错误处理示例

BEGIN TRY
    BEGIN TRAN;

    DELETE FROM hello WHERE id=1;

    INSERT INTO hello (name,age) 
    SELECT name ,age FROM welcome;

    COMMIT TRAN;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK;
    THROW;
END CATCH;
更新:

如果您有非SQL Server错误的其他业务规则,则可以检测T-SQL代码中的条件并引发错误以调用CATCH块并回滚:

BEGIN TRY
    BEGIN TRAN;

    DELETE FROM hello WHERE id=1;

    IF @@ROWCOUNT < 1
    BEGIN
        RAISERROR('Row not found', 16, 1);
    END;

    INSERT INTO hello (name,age) 
    SELECT name ,age FROM welcome;

    COMMIT TRAN;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK;
    THROW;
END CATCH;
开始尝试
开始训练;
从hello中删除,其中id=1;
如果@@ROWCOUNT<1
开始
RAISERROR('未找到行',16,1);
结束;
插入hello(姓名、年龄)
从欢迎列表中选择姓名、年龄;
提交传输;
结束尝试
开始捕捉
如果@TRANCOUNT>0,则回滚;
投掷;
末端捕捉;

有关有用的信息,请参见“谢谢”,AlexYes,我错过了错误处理。感谢DanHi,当我尝试在错误处理中使用2条delete语句时,它已提交。我在问题中对其进行了编辑。在此场景中我应该怎么办?@havin,删除/更新的行从技术上讲不是错误,但可能违反了业务规则。在这种情况下,您需要检测代码中的错误条件并引发错误。我将扩展我的答案以包括这一点。