如何设置初始发电机值?

时间:2013-04-17 09:35:54

标签: firebird

我需要将新的Firebird生成器/序列初始化为现有“旧”表的最大主键值。我尝试了以下但它不工作,我得到错误“令牌未知 - 第6行,第8列选择”。我不能手动执行此操作,因为它必须在许多不同的DB上执行。我正在使用Firebird 2.5.1。

根据http://www.firebirdsql.org/file/documentation/reference_manuals/reference_material/html/langrefupd25-execblock.html这应该有效 - 我做错了什么?

set term #;  
execute block  
as  
declare i int = 0;  
begin  
   i = select max(ID) from OrganizationType_OLU;  
    alter sequence OrganizationType_OLU restart with :i;  
end  
#  
set term ;# 

5 个答案:

答案 0 :(得分:3)

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 ;#

答案 1 :(得分:1)

一般情况下,您可以使用ALTER SEQUENCE

ALTER SEQUENCE sequence-name RESTART WITH <newval>

或旧版选项SET GENERATOR

SET GENERATOR generator-name TO <new-value>

但是,您希望从EXECUTE BLOCK执行此操作,而不能在Firebird中执行从PSQL代码执行DDL。所以我猜answer of rstrelba可能是唯一可用的选项。

请注意,虽然Firebird中的序列不在事务控制之内(它们是原子的),但是如果您是唯一的活动事务,请确保只运行它,否则您可能会将序列重置为无效值。

我强烈建议确保ID的{​​{1}}始终由序列生成,并且绝不允许这些列的用户指定值。这可确保序列值始终有效(即:不会太低,从而导致主键约束违规)。

答案 2 :(得分:0)

你得到的错误(Token unknown - line 6, column 8 select)是因为如果你想使用select as an expression,你必须把它括在括号中,如

i = (select max(ID) from OrganizationType_OLU);

答案 3 :(得分:0)

如果您不想使用EXECUTE BLOCK ,或者仍然使用较旧的Firebird版本(&lt; 2.0),请尝试以下操作:

鉴于GEN_ITEMS_ID是您的生成器名称,您可以通过以下DML语句设置初始生成器值:

SELECT GEN_ID(GEN_ITEMS_ID, 
  (select max(ID) from OrganizationType_OLU) 
  - GEN_ID(GEN_ITEMS_ID, 0)) FROM RDB$DATABASE;

解释here

答案 4 :(得分:0)

EXECUTE BLOCK
AS
DECLARE VARIABLE fMaxID INTEGER;
BEGIN
    SELECT COALESCE(MAX(id),0)
    FROM yourtable
    INTO :fMaxID ;

    EXECUTE STATEMENT('CREATE SEQUENCE YourSequence');
    EXECUTE STATEMENT('ALTER SEQUENCE YourSequence RESTART WITH '||CAST(:fMaxID AS VARCHAR(16)));
END;