Sql server 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
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,删除/更新的行从技术上讲不是错误,但可能违反了业务规则。在这种情况下,您需要检测代码中的错误条件并引发错误。我将扩展我的答案以包括这一点。