【问题标题】:SQL server cursor run twiceSQL 服务器游标运行两次
【发布时间】:2017-11-21 04:50:06
【问题描述】:

假设我有一个游标来查找要更新的数据,

declare @index int;
declare cursor1 cursor for
select table1_index from table where (table1_date < dateadd(dd, -365, getdate()))

open cursor1 
fetch next from cursor1 into @index
while @@fetch_status = 0
begin
  update table1
  set table1_field = SOMETHING
  where table1_index = @index

  if @ERROR = 0
  insert into audit_trail
  values(getdate(), table1_index)

  fetch next from cursor1 into @index
end
close cursor1 
deallocate cursor1 

以上代码在一个存储过程中,每天都会由调度程序运行(例如每天凌晨 12:00)。

我的问题是,如果调度程序运行存储的 pro。在某个时间(例如,17/06/2017 12:00 AM),并且仍在运行(例如在 17/06/2017 05:00 PM)。

如果我在(例如 17/06/2017 03:00 PM)中运行完全相同的代码, 游标会从更新的表中选择数据吗?还是调度程序未更新的表中的数据?

非常感谢。

【问题讨论】:

  • 取决于您的事务模式,但假设 ACID 合规模式和过程之外的事务边界:它将使用第一个过程开始运行之前的数据。
  • 当您有隐式事务时,整个更新语句可能会阻止对表的进一步更新,并且 17/06/2017 03:00 PM,将等待 UPDATE 语句完成。由于这是一个巨大的 UPDATE 语句,它会变成表锁或页锁,它会阻塞其他事务,直到它完成。
  • 我的更新语句似乎并不大,也不会花费太多时间来执行。无论如何,谢谢你的回答:)。
  • 我可以了解有关 ACID 合规模式的一些信息吗?谢谢

标签: sql sql-server


【解决方案1】:
declare cursor1 cursor for
select table1_index from table where (table1_date < dateadd(dd, -365, getdate())) 
and table1_index NOT IN (SELECT table1_index FROM audit_trail)

您需要添加条件and table1_index NOT IN (SELECT table1_index FROM audit_trail)。我希望它对你有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    相关资源
    最近更新 更多