【发布时间】:2022-01-20 17:15:00
【问题描述】:
外循环读取导入表中所有不同的文件名。在事务内部,我调用一个 proc 来处理单个文件的行,在系统中进行各种插入和更新。完成后,我从该文件中删除行。然后我承诺。 今天,我在尝试将空值插入主键时遇到错误。好的,我会弄清楚是什么原因造成的。但是,当我查看导入表时,该文件的所有行都被删除了!为什么?
declare @filename varchar(55);
declare fn cursor for select distinct filename from iox277 order by filename;
begin try
open fn;
fetch next from fn into @filename;
while @@fetch_status = 0 begin
begin transaction
exec spIntake277 @filename; -- insert failed here
delete from iox277 where filename = @filename; -- delete still happened!!
commit;
fetch next from fn into @filename;
end
end try
begin catch
rollback;
close fn;
deallocate fn;
select 'ERROR', error_message();
return;
end catch
这是调用内部 sp 的主存储过程的主体。内部没有交易。内部犯了试图将null插入PK的错误。
【问题讨论】:
-
在您的
catch中调用rollback,它会回滚迄今为止发生的所有事情 - 包括(我有点猜测,因为您没有向我们展示)您在表格中的原始插入。 -
鉴于您的代码 EATS 捕获块中的错误,假设相同的事情发生在您的内部 SP 内部似乎是合乎逻辑的,以便外部 SP 看不到错误。
-
当“...insert failed here...”发生时,事务是被标记为“注定”还是异常被默默吞没?
-
@DaleK 是的。没有嵌套事务。但我认为你的 cmets 让我找到了一个可能的解决方案。在嵌套 proc 中,我尝试设置与父 proc 相同的 catch 块(如上所示)。我通过 select 语句返回错误,就好像它们要返回到应用程序一样,但事实并非如此。我认为我应该在嵌套的过程中使用 throw ,以便错误看起来像外部过程的错误,然后应该触发回滚。下次我要试试。我如何评价你的评论?
-
我通过 select 语句返回错误这是你的问题。不要这样做。重新抛出错误。
标签: sql sql-server azure tsql