DECLARE
v_emp_id NUMBER;
empid NUMBER;
stmt VARCHAR2(1000);
BEGIN
SELECT MAX(emp_id) + 1 INTO v_emp_id FROM employees;
BEGIN
dbms_output.put_line(v_emp_id );
stmt := 'CREATE SEQUENCE emp_seq start with ' ||v_emp_id|| ' increment by 1 NOCYCLE';
EXECUTE IMMEDIATE stmt;
COMMIT;
END;
insert into emp_new select emp_seq.nextval,empname from (select * from employee where active = 0);
dbms_output.put_line(empid);
END;
/
执行上述程序时,我收到以下错误 ORA-06550:第13行,第10栏: PL / SQL:ORA-02289:序列不存在 ORA-06550:第13行,第3栏: PL / SQL:忽略SQL语句
但是当执行以下程序时,它会成功并创建序列。
DECLARE
v_emp_id NUMBER;
empid NUMBER;
stmt VARCHAR2(1000);
BEGIN
SELECT MAX(emp_id) + 1 INTO v_emp_id FROM employees;
BEGIN
dbms_output.put_line(v_emp_id );
stmt := 'CREATE SEQUENCE emp_seq start with ' ||v_emp_id|| ' increment by 1 NOCYCLE';
EXECUTE IMMEDIATE stmt;
COMMIT;
END;
dbms_output.put_line(empid);
END;
/
答案 0 :(得分:4)
在编译时序列不存在,因此编译器返回错误。执行立即执行将在运行时执行,但编译器不知道它将创建稍后在代码中调用的序列。
create or replace procedure createtest as
begin
execute immediate 'create table t1 (c1 number)';
insert into t1 values (1);
end;
/
给出与您的错误相同的错误,因为表t1不存在。所以insert语句无效。编译PL / SQL时出错。
create table t1 (c1 number);
之后我可以创建程序,但是当我这样做时:
exec createtest;
我收到表已经存在的错误。但编译器并不知道我尝试再次创建相同的表,因此它将在运行时返回而不是在编译期间。
如果你真的需要这样做,请做:
create or replace procedure createtest as
begin
execute immediate 'create table t1 (c1 number)';
execute immediate 'insert into t1 values (1)';
end;
/
在你的情况下:
execute immediate 'SELECT emp_seq.nextval FROM dual' INTO empid;
[编辑] 我的理解是你要确保序列设置为max(empid)所以请不要尝试在程序中创建它。然后在过程体执行中创建序列:
select max(empid) into maxempid from employee;
select emp_seq.currval into maxseq from dual;
if(empid-maxseq>0) then
execute immediate 'alter sequence emp_seq increment by ' || empid-maxseq;
end if;
答案 1 :(得分:1)
您应该在创建过程之前创建序列静态。
DROP SEQUENCE emp_seq
/
BEGIN
SELECT MAX(emp_id) + 1 INTO v_emp_id FROM employees;
dbms_output.put_line(v_emp_id );
execute immediate 'CREATE SEQUENCE emp_seq start with ' ||v_emp_id|| ' increment by 1 NOCYCLE';
END;
/
然后创建或替换功能/程序/包......这是指您的序列