2012-11-02 27 views
0

我寫這個函數來設置我的序列currval最大id + 1。但我得到的錯誤如:函數來設置一個序列的currval

ORA-14552: cannot perform a DDL, commit or rollback inside a query or DML 

請幫我解決這個問題。

CREATE OR REPLACE Function createcurrentid (
    model_in IN varchar2, 
    primarykey_in IN VARCHAR2, 
    seq_name IN VARCHAR2) 
    RETURN number 
IS 
    cnumber number; 
    c2  sys_refcursor; 
    c3  sys_refcursor; 
    c6  sys_refcursor; 
    c7  sys_refcursor; 
    c8  sys_refcursor; 
    c9  sys_refcursor; 
    c4 number; 
    c5 number; 
    type result_rec is record (
    id  number, 
    currvalvalue number 
); 
l_result_rec result_rec; 
BEGIN 
open c2 FOR 'SELECT max('||primarykey_in||') AS id FROM '||model_in; 
fetch c2 into c4; 
close c2; 
open c3 FOR 'select '||seq_name||'.currval AS currvalvalue from dual'; 
fetch c3 into c5; 
close c3; 
cnumber:=c4-c5; 
open c6 FOR 'alter sequence'||seq_name||' increment BY'||cnumber; 
commit; 
open c8 FOR 'select '||seq_name||'.nextval from dual'; 
commit; 
open c9 FOR 'select '||seq_name||'.CURRVAL from dual'; 
commit; 
open c7 FOR 'alter sequence'||seq_name||' increment BY 1'; 
commit; 
RETURN cnumber; 
END; 

回答

3

所有這些打開的遊標對於返回單行,或根本沒有,似乎不是很有用,很可能是您的問題的源語句。

嘗試類似如下:

create or replace function createcurrentid (
    model_in in varchar2, 
    primarykey_in in varchar2, 
    seq_name in varchar2) 
    return number 
is 
    maxval number; 
    lastval number; 
    delta number; 
    nextval number; 
begin 
execute immediate 'select max('||primarykey_in||') as id from '||model_in 
    into maxval; 
execute immediate 'select '||seq_name||'.nextval from dual' 
    into lastval; 
delta:=maxval-lastval; 

execute immediate 'alter sequence '||seq_name||' increment by '||delta; 
execute immediate 'select '||seq_name||'.nextval from dual' 
    into nextval; -- this var needs to be read for the sequence to increment 
execute immediate 'alter sequence '||seq_name||' increment by 1'; 
return delta; 
end; 

記住DDL執行一個隱含的承諾,所以你必須明確那些是多餘的。

此外,我相信這本質上是活潑的,但是對於一次性修復它可能沒問題。

相關問題