2016-08-03 76 views
0

今天我試圖在匿名塊內創建一個序列。我的要求是當序列達到最大值時,它應該自動刪除。所以,我已經執行了下面的代碼,但它顯示錯誤,如「PL/SQL:ORA-02289:序列不存在」。不能在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

問題是,Oracle試圖解析您的匿名塊,然後執行。如果序列不存在,比上會有此行的錯誤ORA-02289:

SELECT SEQ_GEN.NEXTVAL INTO V_NUM FROM DUAL; 

,你不能抓住它,因爲在解析發生。你應該動態地獲得nextval。如果該序列存在,則會在該行上出現錯誤:

EXECUTE IMMEDIATE 'DROP SEQUENCE SEQ_GEN'; 

但是這個錯誤會在其他人中被捕獲。另一件事是,當達到最大值時,你可以使用直接的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;