使用现有值初始化生成器

时间:2016-07-21 07:29:02

标签: firebird firebird2.5

我正在尝试使用某个表中的值设置一个生成器,我已经看到了这个问题How to set initial generator value?并做了他们的建议,但我不知道我在哪里错了。

set term #   
execute block    
as  
declare i int = 0;    
begin  
  i = (select max(some_col) from Table);  
  gen_id(some_gen,-(gen_id(some_gen,0))); ---set some_gen to 0  
  gen_id(some_gen,:i);  --- set to i
end #  
set term ;#

2 个答案:

答案 0 :(得分:2)

如果您想使用“执行块”,您可以使用以下内容:

execute block    
as  
declare i int = 0;    
begin  
  i = (select max(some_col) from some_table);
  execute statement ('set generator MY_GENERATOR to ' || :i);
end

答案 1 :(得分:2)

您的代码存在的问题是您无法独立执行gen_id;解析器只在可以有值的地方(例如在语句或赋值中)期望gen_id(或更准确地说:函数调用)。您需要将其返回值分配给参数,例如:

set term #;
execute block    
as  
declare i int = 0;    
declare temp int = 0;
begin  
  i = (select max(id) from items);  
  temp = gen_id(GEN_ITEMS_ID, -(gen_id(GEN_ITEMS_ID, 0))); ---set some_gen to 0  
  temp = gen_id(GEN_ITEMS_ID, :i);  --- set to i
end #  
set term ;#

请注意,更改这样的序列是有风险的:如果使用相同的序列有任何交错操作,您实际上可能无法获得预期的结果(序列可能会以不同的方式结束)值小于i,当您在减去当前值(设置为0)之后和添加i之前,当另一个事务使用序列时,您可能会遇到重复键错误。

正如评论中所述,您还可以使用以下代码替换代码:

set term #;
execute block    
as  
declare i int = 0;    
declare temp int = 0;
begin  
  i = (select max(id) from items);  
  temp = gen_id(GEN_ITEMS_ID, :i - gen_id(GEN_ITEMS_ID, 0));
end #  
set term ;#

在一个语句中执行此操作将降低交错操作的风险(尽管它不会完全删除它)。