Oracle 编译存储过程时出错

Oracle 编译存储过程时出错,oracle,plsql,Oracle,Plsql,我在下面编写这个存储过程,但在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_v

我在下面编写这个存储过程,但在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  
错误(7,1):PLS-00103:在预期以下情况之一时遇到符号“BEGIN”:(使用外部确定性并行将authid作为群集顺序启用流水线结果缓存符号);“已替换为“BEGIN”以继续。

错误(22,25):PLS-00103:遇到符号“下降”当需要以下选项之一时:&&=+;at in is mod rements not rem return return or!=或~=>=第一条错误消息告诉您在
开始之前缺少了一些内容,甚至在“需要时”列表中提到了两个可能的选项。您需要将其更改为:

PROCEDURE TEST_TABLE IS
--                   ^^
或者,如果您愿意,可以使用
AS
而不是
IS

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

...
  dbms_output.put_line(''drop partition completed'');
--                     ^                         ^
END;';
你可以用这个来代替

我不知道为什么要进行两个级别的动态SQL;您可以执行
dbms_output()
并静态计算
cc.high_value
,然后决定是否进行
alter调用
,仅使用该部分动态(如@BarbarosÖzhan所示,因此我不会重复!)。或者在游标查询中进行高值检查


我仍然得到异常错误(1,14):PLS-00304:无法编译没有规范的“测试表”主体

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

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
/
让包名与其中的过程相同有点奇怪和混乱

但是,也许您实际上根本不想要一个包,并且正在尝试创建一个独立的过程,在这种情况下,只需删除包体部分:

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


我强烈建议您去掉异常处理程序,我已经把它从这些提纲中删去了-您应该让任何异常流回到调用方。您不知道调用此处理程序的人甚至会启用输出,因此可能甚至看不到您正在打印的消息。只有捕获到您可以处理和需要的异常在这一点上进行处理。

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

PROCEDURE TEST_TABLE IS
--                   ^^
或者,如果您愿意,可以使用
AS
而不是
IS

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

...
  dbms_output.put_line(''drop partition completed'');
--                     ^                         ^
END;';
你可以用这个来代替

我不知道为什么要进行两个级别的动态SQL;您可以执行
dbms_output()
并静态计算
cc.high_value
,然后决定是否进行
alter调用
,仅使用该部分动态(如@BarbarosÖzhan所示,因此我不会重复!)。或者在游标查询中进行高值检查


我仍然得到异常错误(1,14):PLS-00304:无法编译没有规范的“测试表”主体

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

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
/
让包名与其中的过程相同有点奇怪和混乱

但是,也许您实际上根本不想要一个包,并且正在尝试创建一个独立的过程,在这种情况下,只需删除包体部分:

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


我强烈建议您去掉异常处理程序,我已经把它从这些提纲中删去了-您应该让任何异常流回到调用方。您不知道调用此处理程序的人甚至会启用输出,因此可能甚至看不到您正在打印的消息。只有捕获到您可以处理和需要的异常在这一点上进行处理。

您需要如下正确引用(
程序测试表之后的另一个
关键字)
“感谢Alex让我醒来”):

作为一点建议,为避免混淆,请使用与过程不同的名称,例如
PKG\u TEST\u TABLE

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

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

您需要在下面正确引用(并且在
程序测试表
“感谢Alex,他让我觉醒了”):

作为一点建议,为避免混淆,请使用与过程不同的名称,例如
PKG\u TEST\u TABLE

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

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

我仍然收到异常错误(1,14):PLS-00304:如果没有规范,则无法编译“TEST_TABLE”的主体。这是一个完全不同的问题。您已经发布了包主体的代码。您必须首先创建包规范。您已经创建了吗?请告知我们是否需要以类似的方式创建包创建或替换包PKG_TEST_TABLE作为PROCEDURE TEST_TABLE;END PKG_TEST_TABLE;这就是我编辑的答案显示的,是的;但是您更改了名称-规范和主体必须具有相同的名称(显然,希望如此)。我仍然收到异常错误(1,14):PLS-00304:如果没有规范,则无法编译“TEST_TABLE”的主体。这是一个完全不同的问题。您已经发布了包主体的代码。您必须首先创建包规范。您已经创建了吗?请告知我们是否需要以类似的方式创建包创建或替换包PKG_TEST_TABLE作为PR过程测试表;结束包装测试选项卡