我写了这个函数来将我的序列的currval设置为最大id + 1。但我得到的错误如下:
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;
答案 0 :(得分: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执行隐式提交,因此您拥有的显式提交是多余的。
此外,我相信这本身就很有趣,但对于一次性修复,它可能还行。