【问题标题】:Inserts into Sybase table in the cursor fetch loop在游标提取循环中插入 Sybase 表
【发布时间】:2014-02-06 13:38:28
【问题描述】:

我正在编写一个带有游标的 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

【问题讨论】:

  • 您使用的是哪种 Sybase 产品?

标签: tsql sybase sap-ase


【解决方案1】:

我也对这种行为感到惊讶。游标只遍历行,它们不能不受循环期间的变化的影响。 manual 声明如下:

对所有页锁定表的搜索或定位更新可以更改 行的位置;例如,如果它更新了 聚集索引。光标不跟踪行;它仍然存在 位于原始位置的下一行之前。 在后续 fetch 返回之前,不允许定位更新 下一行。更新的行可能对游标可见一秒钟 时间,如果该行在搜索顺序中移动到后面的位置

我的解决方案是插入一个临时表并在最后将结果复制回来,这也将过程加快了大约 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2021-12-14
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多