Усечение таблицы в хранимой процедуре - PullRequest
47 голосов
/ 09 марта 2009

Когда я запускаю следующее в оболочке Oracle, оно прекрасно работает

truncate table table_name

Но когда я пытаюсь поместить его в хранимую процедуру

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    truncate table table_name;
END test;
/

не получается с

ERROR line 3, col 14, ending_line 3, ending_col 18, Found 'table', Expecting:  @   ROW  or   (   or   .   or   ;   :=

Почему?

Ответы [ 4 ]

101 голосов
/ 09 марта 2009

Все операторы DDL в Oracle PL / SQL должны использовать Execute Immediate перед оператором. Следовательно, вы должны использовать:

execute immediate 'truncate table schema.tablename';
17 голосов
/ 09 марта 2009

Помимо немедленного выполнения, вы также можете использовать

DBMS_UTILITY.EXEC_DDL_STATEMENT('TRUNCATE TABLE tablename;');

Оператор не выполняется, поскольку хранимый процесс выполняет DDL, а некоторые экземпляры DDL могут сделать недействительным сохраненный процесс. При использовании подходов немедленного выполнения или exec_ddl DDL реализуется через неразобранный код.

При этом вам необходимо учитывать тот факт, что DDL выдает неявную фиксацию как до, так и после выполнения.

11 голосов
/ 09 марта 2009

попробуйте следующий код

execute immediate 'truncate table tablename' ;
10 голосов
/ 15 февраля 2013

Вы должны знать, что невозможно напрямую выполнить инструкцию DDL, как вы делаете для DML из блока PL / SQL, потому что PL / SQL не поддерживает позднюю привязку напрямую, она поддерживает только привязку во время компиляции, что хорошо для DML. следовательно, чтобы преодолеть этот тип проблемы, оракул предоставил подход динамического SQL, который можно использовать для выполнения операторов DDL. Подход динамического sql заключается в анализе и связывании строки sql во время выполнения. Также вы должны помнить, что операторы DDL по умолчанию являются автоматическими коммитами, поэтому вы должны быть осторожны с любым оператором DDL, использующим подход динамического SQL, если у вас есть некоторый DML (который должен быть зафиксирован явно с использованием TCL) перед выполнением DDL в сохраненная процедура / функция.

Вы можете использовать любой из следующих динамических подходов SQL для выполнения инструкции DDL из блока pl / sql.

1) Выполнить немедленно

2) Пакет DBMS_SQL

3) DBMS_UTILITY.EXEC_DDL_STATEMENT (parse_string IN VARCHAR2);

Надеюсь, это ответит на ваш вопрос с объяснением.

...