Reputation: 1
Today I have tried to create a sequence inside anonymous block. My requirement is when sequence is reached the maxvalue then it should be dropped automatically. So, I have executed the below code but it shows error like "PL/SQL: ORA-02289: sequence does not exist".
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;
/
Can anyone assist me to solve this issue?
Upvotes: 0
Views: 2514
Reputation: 1948
The problem is, that Oracle try to parse your anonymous block, before to execute. If the sequence does not exist, than there will be error ORA-02289 on this line:
SELECT SEQ_GEN.NEXTVAL INTO V_NUM FROM DUAL;
and you cannot catch it, because happens on parse. You should get nextval dynamicly. If the sequence exists, there will be error on this line:
EXECUTE IMMEDIATE 'DROP SEQUENCE SEQ_GEN';
but this error will be caught in WHEN OTHERS. Another thing is that you can use direct ORA-08004 when the max value is reached.
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;
Upvotes: 2
Reputation: 9886
Try this.
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;
/
Upvotes: 0