0

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

1 回答 1

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

我相信这本质上是活泼的,但对于一次性修复它可能没问题。

于 2012-11-02T13:49:05.713 回答