2016-08-03 73 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;