2013-04-17 35 views
1

我需要将一个新的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 ;# 

回答

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

谢谢你,这让我走向了正确的方向。完全正常工作的SQL如下所示:set term#; 执行块 as declare i int = 0; declare g int = 0; begin i =(从OrganizationType_OLU中选择max(ID)); g =(从RDB $ DATABASE)选择gen_id(OrganizationType_OLU, - (gen_id(OrganizationType_OLU,0)))); g =(从RDB $ DATABASE)选择gen_id(OrganizationType_OLU,(从OrganizationType_OLU中选择max(ID))); 结束 # 设定项;# –

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可能是唯一的选择。

要知道,虽然序列是在火鸟(它们的原子)事务控制之外的,所以一定要确保你只运行它,如果你是唯一的活动事务,否则你可能会在序列重置为无效值。

我强烈建议确保的ID总是按顺序生成,并且绝不允许用户为这些列指定值。这确保序列值始终有效(即:不能太低,导致主键约束违规)。

0

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

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

谢谢,这让我的第7行。 –

0

如果你不想使用EXECUTE BLOCK或者如果你仍然使用旧的火鸟版本(< 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

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;