在游标提取循环中插入Sybase表

时间:2014-02-06 13:38:28

标签: tsql sybase sybase-ase

我正在编写一个Sybase存储过程,其中一个游标从表中获取记录并重新插入记录。令人惊讶的是,我发现fetches看到amd返回记录插入到同一个循环中。在某些情况下,这会导致无限循环,有时循环会结束一些额外记录。浏览Sybase文档我找不到治愈方法。事务隔离没有帮助,因为我们在单个事务中执行操作。当然,我可以通过插入循环中的临时表然后在循环结束后插回主表来解决问题。 但问题仍然存在:如何将光标提取与插入隔离到同一个表? 伪代码如下:

create table t (v int)
go
insert into t(v) values (1)
create procedure p as
begin
 declare @v int
 declare c cursor for select v from t
 begin transaction
 open c
 while 1=1 begin
  fetch c into @v
  if (@@sqlstatus != 0) break
  insert into t (v) values (@v+1)
 end
 close c
 commit
end
go
exec p
go

1 个答案:

答案 0 :(得分:0)

我也对这种行为感到惊讶。游标只迭代行,它们在循环期间不会受到变化的影响。 manual说明了这一点:

  

对所有页锁定表的搜索或定位更新可能会发生变化   排的位置;例如,如果它更新a的键列   聚集索引。光标不跟踪行;它仍然存在   位于原始位置的下一行之前。   在后续提取返回之前,不允许定位更新   下一行。更新的行可能对光标可见一秒钟   时间,如果行移动到搜索顺序中的稍后位置

我的解决方案是插入临时表并在结尾处复制结果,这也加快了大约10倍的过程。

的伪代码:

select * into #results from OriginalTable where 1<>1 --< create temp table with same columns
WHILE fetch...
BEGIN
      insert into #results
      select -your-results-here
END
insert into OriginalTable select * from #results