ошибка при компиляции хранимой процедуры - PullRequest
0 голосов
/ 22 февраля 2019

Я пишу эту хранимую процедуру ниже, но я также получаю исключение при компиляции процедуры в 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  

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Вам нужно сделать правильную цитату, как показано ниже (и еще одно ключевое слово is сразу после PROCEDURE TEST_TABLE " благодаря Алексу, который заставил меня разбудить "):

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;
/
0 голосов
/ 22 февраля 2019

Первое сообщение об ошибке говорит вам, что чего-то не хватает до BEGIN, и даже упоминает две возможные опции в списке «при ожидании».Вам нужно изменить его на:

PROCEDURE TEST_TABLE IS
--                   ^^

Или вы можете использовать AS вместо IS, если предпочитаете ...

Вторая ошибка заключается в том, что у вас есть строковый литералвстроенный в ваш динамический SQL, и вы не избежали одинарных кавычек, хотя у вас есть где-то еще:

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

Вместо этого вы можете использовать альтернативный механизм *1013*.

Я не уверен, почему вы делаете два уровня динамического SQL;Вы можете сделать dbms_output() и оценить cc.high_value статически, и решить, делать ли alter call, только с этой частью, динамической (как показало @ BarbarosÖzhan, поэтому я не буду повторять это!).Или выполните проверку высокого значения в запросе курсора.

Я все еще получаю исключение Ошибка (1,14): PLS-00304: не удается скомпилировать тело 'TEST_TABLE' без его спецификации

Если вы хотите пакет, то вы должны создать его спецификацию, прежде чем пытаться создать его тело:

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
/

Подробнее .

Я бы настоятельно рекомендовал вам избавиться от обработчика исключений, и я упустил это из этих контуров - вы должны позволить любому исключению перетекать обратно к вызывающей стороне.Вы не знаете, что кто бы ни звонил, у него даже будет включен вывод, поэтому он может даже не увидеть сообщение, которое вы печатаете.Только когда-либо ловить исключения, которые вы можете обработать и должны обрабатывать в этот момент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...