select 用于存储过程中的更新(同时递增一个字段)

select for update in stored procedure (concurrently increment a field)

当多个用户连接时,我想在 Informix 12.1 中检索一个字段的值并安全地递增它。

用 C 术语来说,我想要的是 lastnumber = counter++; 在并发环境中。

文档提到了一种方法,即让每个人都使用等待参数进行连接、锁定行、读取数据、递增并释放锁。

这就是我尝试的方法:

begin work;

  select 
    lastnum 
  from tbllastnums
  where id = 1
  for update;

而且我可以看到该行被锁定,直到我提交或结束我的会话。

然而,当我将其放入存储过程时:

create procedure "informix".select_for_update_test();

  define vLastnum decimal(15);

begin work;

  select 
    lastnum 
  into vLastnum
  from tbllastnums
  where id = 1
  for update;

commit;

end procedure;

数据库给我一个语法错误。 (尝试过不同的编辑器)那么为什么在存储过程中编写 for update 子句会出现语法错误?有替代方案吗?

编辑

这是我最终得到的结果:

DROP TABLE if exists tstcounter;
^!^
CREATE TABLE tstcounter
(
   id       INTEGER   NOT NULL,
   counter  INTEGER   DEFAULT 0 NOT NULL
)
EXTENT SIZE 16
NEXT SIZE 16
LOCK MODE ROW;
^!^
ALTER TABLE tstcounter
   ADD CONSTRAINT PRIMARY KEY (id)
   CONSTRAINT tstcounter00;

^!^
insert into tstcounter values(1, 0);
^!^
select * from tstcounter;
^!^
drop function if exists tstgetlastnumber;
^!^
create function tstgetlastnumber(pId integer) 
returning integer as lastCounter

  define vCounter integer;

  foreach curse for 
    select counter into vCounter from tstcounter where id = pId 

    update tstcounter set counter = vCounter + 1 where current of curse;

    return vCounter with resume;
  end foreach;


end function;
^!^

SPL 和光标 'FOR UPDATE'

如果您设法找到手册的正确位置——Updating or Deleting Rows Identified by Cursor Name under the FOREACH Informix Guide to SQL: Syntax 手册的 SPL(存储过程语言)部分中的语句——那么您将查找魔法资料:

Specify a cursor name in the FOREACH statement if you intend to use the WHERE CURRENT OF cursor clause in UPDATE or DELETE statements that operate on the current row of cursor within the FOREACH loop. Although you cannot include the FOR UPDATE keywords in the SELECT ... INTO segment of the FOREACH statement, the cursor behaves like a FOR UPDATE cursor.

因此,您需要创建一个带有游标名称的 FOREACH 循环并从那里获取它。


访问手册

顺便说一下,如果你去 IBM Informix Knowledge Center 看到这个图标:

这是 'show table of contents' 图标,您需要按下它才能查看导航到手册的有用信息。如果您看到这个图标:

它是 'hide table of contents' 图标,但您应该能够看到左侧下方的内容。我花了一段时间才发现这个技巧。我不知道为什么默认情况下内容对我来说是隐藏的,但我认为如果其他人也遇到这种情况,那将是一个用户体验设计错误。