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