【问题标题】:getting error while compiling the stored procedure编译存储过程时出错
【发布时间】:2019-02-22 17:21:40
【问题描述】:

我正在下面的存储过程中写这个,但是在 oracle 中编译过程时我也遇到了异常,下面是过程

CREATE OR REPLACE PACKAGE BODY TEST_TABLE AS 
PROCEDURE TEST_TABLE         


--This procedure will delete partitions for the following tables:
--TEST_TABLE
BEGIN
  FOR cc IN
  (
  SELECT partition_name, high_value
  FROM user_tab_partitions
  WHERE table_name = 'TEST_TABLE'
  )

LOOP
    EXECUTE IMMEDIATE 'BEGIN               
IF sysdate >= ADD_MONTHS(' || cc.high_value || ', 3) THEN                  
EXECUTE IMMEDIATE                     
''ALTER TABLE TEST_TABLE DROP PARTITION ' || cc.partition_name || '                     
'';               
END IF;    
  dbms_output.put_line('drop partition completed');        
END;';
  END LOOP;

  exception
                when others then
                                dbms_output.put_line(SQLERRM);

END;

END; 
/

我在编译时遇到的异常是请告知如何克服这个问题。

Error(7,1): PLS-00103: Encountered the symbol "BEGIN" when expecting one of the following:     ( ; is with authid as cluster order using external    deterministic parallel_enable pipelined result_cache The symbol ";" was substituted for "BEGIN" to continue. 

Error(22,25): PLS-00103: Encountered the symbol "DROP" when expecting one of the following:     * & = - + ; < / > at in is mod remainder not rem return    returning <an exponent (**)> <> or != or ~= >= <= <> and or    like like2 like4 likec between into using || bulk member    submultiset  

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    您需要如下正确引用(以及在PROCEDURE TEST_TABLE 之后再添加一个is 关键字“感谢让我醒来的亚历克斯”):

    CREATE OR REPLACE PACKAGE BODY PKG_TEST_TABLE IS 
     PROCEDURE TEST_TABLE IS        
    
    --This procedure will delete partitions for the following tables:
    --TEST_TABLE
     BEGIN
      FOR cc IN
      (
      SELECT partition_name, high_value
      FROM user_tab_partitions
      WHERE table_name = 'TEST_TABLE'
      )    
      LOOP
       BEGIN               
         IF sysdate >= ADD_MONTHS(cc.high_value, 3) THEN                  
          EXECUTE IMMEDIATE                     
          'ALTER TABLE TEST_TABLE DROP PARTITION ' || cc.partition_name;                   
           Dbms_Output.Put_Line('Dropping partition is completed.');        
         END IF;
       END;
      END LOOP;
    
      EXCEPTION WHEN Others THEN Dbms_Output.Put_Line( SQLERRM );
    
     END TEST_TABLE;
    
    END PKG_TEST_TABLE; 
    /
    

    作为一个小建议,为包使用与过程不同的名称,例如PKG_TEST_TABLE,以免混淆。

    编辑:当然,您需要在包的主体部分之前为包创建规范部分:

    CREATE OR REPLACE PACKAGE PKG_TEST_TABLE IS 
     PROCEDURE TEST_TABLE;
    END PKG_TEST_TABLE;
    /
    

    【讨论】:

    • Ozhan 我仍然收到异常 Error(1,14): PLS-00304: cannot compile body of 'TEST_TABLE' without its specification
    • @fkljfklgfjhkgbng 但我提到了包的主体,问题没有关于规范部分的信息。
    【解决方案2】:

    第一条错误消息告诉您BEGIN 之前缺少某些内容,甚至在“期待时”列表中提到了两个可能的选项。您需要将其更改为:

    PROCEDURE TEST_TABLE IS
    --                   ^^
    

    如果您愿意,也可以使用AS 代替IS...

    第二个错误是因为您在动态 SQL 中嵌入了一个字符串文字,并且您没有转义单引号,尽管您在其他地方有:

    ...
      dbms_output.put_line(''drop partition completed'');
    --                     ^                         ^
    END;';
    

    您可以改用alternative quoting mechanism

    我不确定您为什么要执行两个级别的动态 SQL;您可以静态地执行dbms_output() 并评估cc.high_value,并决定是否使alter call 仅具有动态部分(正如@BarbarosÖzhan 所展示的,所以我不会重复!)。或者在游标查询中做高值检查。

    我仍然收到异常 Error(1,14): PLS-00304: cannot compile body of 'TEST_TABLE' without its specification

    如果你想要一个包,那么你必须在尝试创建它的主体之前创建它的规范:

    CREATE OR REPLACE PACKAGE TEST_TABLE AS 
    PROCEDURE TEST_TABLE;
    END TEST_TABLE;
    /
    
    CREATE OR REPLACE PACKAGE BODY TEST_TABLE AS 
    PROCEDURE TEST_TABLE IS
    BEGIN
      FOR cc IN
      ...
      LOOP
        ...
      END LOOP;
    END TEST_TABLE; -- end of procedure
    END TEST_TABLE; -- end of package
    /
    

    将包名与其中的过程同名有点奇怪和混乱。

    但也许你实际上根本不想要一个包,而是试图创建一个独立的过程,在这种情况下,只需删除 package-body 部分:

    CREATE OR REPLACE PROCEDURE TEST_TABLE AS
    BEGIN
      FOR cc IN
      ...
      LOOP
        ...
      END LOOP;
    END TEST_TABLE; -- end of procedure
    /
    

    Read more.

    我强烈建议您摆脱异常处理程序,并且我已将其排除在这些大纲之外 - 您应该让任何异常流回调用者。您不知道调用它的人甚至会启用输出,因此很可能甚至看不到您正在打印的消息。只捕获您当时可以处理和需要处理的异常。

    【讨论】:

    • 我仍然收到异常 Error(1,14): PLS-00304: cannot compile body of 'TEST_TABLE' without its specification
    • 这是一个完全不同的问题。您已经发布了包体的代码。您必须首先创建包规范。你做到了吗?
    • poope 请告知我们是否需要以类似的方式创建包创建或替换包 PKG_TEST_TABLE AS PROCEDURE TEST_TABLE;结束 PKG_TEST_TABLE;
    • 这就是我编辑的答案所显示的,是的;但是您更改了名称 - 规范和正文必须具有相同的名称(显然,希望如此)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多