2013-04-17 153 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;