1

我需要将新的 Firebird 生成器/序列初始化为现有“旧”表的最大主键值。我尝试了以下但它不起作用,我收到错误“令牌未知 - 第 6 行,第 8 列选择”。我不能手动执行此操作,因为它必须在许多不同的数据库上执行。我正在使用火鸟 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 ;# 
4

5 回答 5

3

一般来说,您可以使用ALTER SEQUENCE

ALTER SEQUENCE sequence-name RESTART WITH <newval>

或传统选项SET GENERATOR

SET GENERATOR generator-name TO <new-value>

但是,您想从 an 中执行此操作,EXECUTE BLOCK并且您不能从 PSQL 代码执行 DDL 在 Firebird 中是不允许的。所以我想rstrelba 的答案可能是唯一可用的选择。

请注意,尽管序列在 Firebird 中的事务控制之外(它们是原子的),但请确保仅在您是唯一活动事务时运行它,否则您可能会将序列重置为无效值。

我强烈建议确保IDforOrganizationType_OLU始终按顺序生成,并且永远不允许用户为这些列指定值。这确保了序列值始终有效(即:不会太低,导致违反主键约束)。

于 2013-04-17T10:37:11.910 回答
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 ;#
于 2013-04-17T09:54:44.920 回答
1
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;
于 2018-02-21T13:32:09.077 回答
0

您得到 ( Token unknown - line 6, column 8 select) 的错误是因为如果您想select用作表达式,则必须将其括在括号中,例如

i = (select max(ID) from OrganizationType_OLU);
于 2013-04-17T11:41:59.777 回答
-1

如果您不想使用EXECUTE BLOCK或仍使用较旧的 Firebird 版本 (<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;

在这里解释。

于 2016-12-09T15:44:55.303 回答