用于设置序列的currval的函数

时间:2012-11-02 12:12:15

标签: oracle oracle11g

我写了这个函数来将我的序列的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;

1 个答案:

答案 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执行隐式提交,因此您拥有的显式提交是多余的。

此外,我相信这本身就很有趣,但对于一次性修复,它可能还行。