2016-10-13 20 views
2
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文が無視されます。を作成および使用シーケンスをOracleストアドプロシージャに - シーケンス

ただし、以下の手順を実行すると正常に実行され、順序が作成されます。

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; 
    /

答えて

3

コンパイル時にシーケンスが存在しないため、コンパイラがエラーを返します。 Execute immediateは実行時に実行されますが、コンパイラは後でコードで呼び出すシーケンスを作成するかどうかを知りません。

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; 

を私は理解してどのような[EDIT] はあなたが順序であることを確認したいです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; 
+0

感謝:)私はselect文と挿入で配列を使用していますあなたの配列をいうFUNCTION/PROCEDURE/PACKAGEを.... REPLACE。どのようにそれを行う上の任意のアイデア?申し訳ありませんが、私は非常にほとんどのアイデアがオラクルの手続きを持っています – Doubtful

+0

すぐに実行する 'SELECT emp_seq.nextval FROM dual' INTO empid;これは、empidにselectおよびreturnの値で新しく作成されたシーケンスを使用する方法です。 – Kacper

+0

employeeからemp_new select(emp_seq.nextval、empname)に挿入します。 – Doubtful

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; 
/

してから、CREATE OR

関連する問題