无法在PLSQL中的匿名块中创建和删除序列

时间:2016-08-03 03:17:06

标签: oracle plsql

今天我尝试在匿名块中创建一个序列。我的要求是当序列达到maxvalue然后应该自动删除。所以,我已经执行了下面的代码,但它显示的错误如“PL / SQL:ORA-02289:序列不存在”。

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 个答案:

答案 0 :(得分:2)

问题是,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;

答案 1 :(得分: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;
/