2016-08-03 13 views
0

今日、私は匿名ブロック内でシーケンスを作成しようとしました。私の要件は、シーケンスがmaxvalueに達したときに自動的に削除されるべきときです。したがって、以下のコードを実行しましたが、 "PL/SQL:ORA-02289:sequence does not exist"のようなエラーが表示されます。PLSQLの匿名ブロックでシーケンスを作成および削除することができません

CODE: 

DECLARE 
V_NUM NUMBER:=0; 
V_QUERY VARCHAR2(2000); 
CNT NUMBER := 0; 
BEGIN 
V_QUERY:= 'CREATE SEQUENCE SEQ_GEN START WITH 100 INCREMENT BY 10 MAXVALUE 200'; 
EXECUTE IMMEDIATE 'DROP SEQUENCE SEQ_GEN'; 
EXECUTE IMMEDIATE V_QUERY; 

FOR I IN 1..11 LOOP 
SELECT SEQ_GEN.NEXTVAL INTO V_NUM FROM DUAL; 
DBMS_OUTPUT.PUT_LINE(V_NUM); 
IF V_NUM >= 200 THEN 
EXECUTE IMMEDIATE 'DROP SEQUENCE SEQ_GEN'; 
DBMS_OUTPUT.PUT_LINE('sequence has reached maximum value'); 
END IF; 
END LOOP; 

SELECT COUNT(1) INTO CNT FROM USER_SEQUENCES WHERE SEQUENCE_NAME = 'SEQ_GEN'; 
DBMS_OUTPUT.PUT_LINE(CNT); 

EXCEPTION 
WHEN OTHERS THEN 
DBMS_OUTPUT.PUT_LINE(SQLERRM); 
END; 
/

この問題の解決に役立つ人はいますか?

+2

行7は、行8で作成される前にシーケンスを削除しようとします。これをデバッグするには、例外ブロックを削除します。デフォルトでは、Oracleは実行を停止し、エラーと行番号を出力します。これにより、問題を迅速に指摘する必要があります。 –

答えて

0

これを試してください。

DECLARE 
    V_NUM  NUMBER := 0; 
    V_QUERY VARCHAR2 (2000); 
    CNT  NUMBER := 0; 
BEGIN 
    V_QUERY :='CREATE SEQUENCE SEQ_GEN START WITH 100 INCREMENT BY 10 MAXVALUE 200'; 

    EXECUTE IMMEDIATE V_QUERY; 

    FOR I IN 1 .. 11 
    LOOP  
     V_QUERY :='SELECT SEQ_GEN.NEXTVAL FROM DUAL'; 

     EXECUTE IMMEDIATE V_QUERY INTO V_NUM; 

     DBMS_OUTPUT.PUT_LINE (V_NUM); 

     IF V_NUM >= 200 
     THEN 
     EXECUTE IMMEDIATE 'DROP SEQUENCE SEQ_GEN'; 

     DBMS_OUTPUT.PUT_LINE ('sequence has reached maximum value'); 
     END IF; 
    END LOOP; 

    SELECT COUNT (1) 
    INTO CNT 
    FROM USER_SEQUENCES 
    WHERE SEQUENCE_NAME = 'SEQ_GEN'; 

    DBMS_OUTPUT.PUT_LINE (CNT); 
EXCEPTION 
    WHEN OTHERS 
    THEN 
     DBMS_OUTPUT.PUT_LINE (SQLERRM); 
END; 
/
1

問題は、実行する前に匿名ブロックを解析しようとしていることです。シーケンスが存在しない場合は、そこにこの行のエラーORA-02289になりますより:パースに起こるので

SELECT SEQ_GEN.NEXTVAL INTO V_NUM FROM DUAL; 

、あなたは、それをキャッチすることはできません。あなたは動的にnextvalを取得する必要があります。シーケンスが存在する場合、次の行にエラーが発生します。

EXECUTE IMMEDIATE 'DROP SEQUENCE SEQ_GEN'; 

このエラーは、他のときに検出されます。もう1つの点は、最大値に達すると直接ORA-08004を使用できることです。

DECLARE 
    sequence_reached_max_value EXCEPTION; 
    PRAGMA EXCEPTION_INIT (sequence_reached_max_value, -8004); 
    sequence_exists    EXCEPTION; 
    PRAGMA EXCEPTION_INIT (sequence_exists, -955); 
    V_NUM      NUMBER := 0; 
    V_QUERY      VARCHAR2 (2000); 
    CNT       NUMBER := 0; 
BEGIN 
    V_QUERY := 'CREATE SEQUENCE SEQ_GEN START WITH 100 INCREMENT BY 10 MAXVALUE 200'; 

    BEGIN 
     EXECUTE IMMEDIATE V_QUERY; 
    EXCEPTION 
     WHEN sequence_exists THEN 
     EXECUTE IMMEDIATE 'DROP SEQUENCE SEQ_GEN'; 
     EXECUTE IMMEDIATE V_QUERY; 
    END; 

    BEGIN 
     FOR I IN 1 .. 21 
     LOOP 
     EXECUTE IMMEDIATE 'SELECT SEQ_GEN.NEXTVAL FROM DUAL' into V_NUM; 

     DBMS_OUTPUT.PUT_LINE (V_NUM); 
     END LOOP; 
    EXCEPTION 
     WHEN sequence_reached_max_value THEN 
     EXECUTE IMMEDIATE 'DROP SEQUENCE SEQ_GEN'; 
     DBMS_OUTPUT.PUT_LINE ('sequence has reached maximum value'); 
    END; 

    SELECT COUNT (1) 
    INTO CNT 
    FROM USER_SEQUENCES 
    WHERE SEQUENCE_NAME = 'SEQ_GEN'; 

    DBMS_OUTPUT.PUT_LINE (CNT); 
EXCEPTION 
    WHEN OTHERS THEN 
     DBMS_OUTPUT.PUT_LINE (SQLERRM); 
END; 
関連する問題