Я пытаюсь создать хранимую процедуру Oracle, которая примет имя таблицы в качестве параметра. Процедура затем восстановит все индексы на таблице.
Моя проблема, я получаю ошибку при использовании команды ALTER из хранимой процедуры, как будто PLSQL не позволяет ту команду.
Вот несколько возможностей. Во-первых, вам придется рассматривать SQL как динамический SQL. Во-вторых, операторы Oracle DDL не могут быть запущены в транзакции (или они завершают текущую транзакцию и сами не могут быть отменены). Это может повлиять на то, можете ли вы использовать их в хранимых процедурах или где вы можете использовать хранимые процедуры, которые их содержат.
Если ничего из вышеперечисленного не применимо вообще - легко может быть что-то еще неправильное - я предлагаю опубликовать некоторый код.
Передача имен объектов схемы в качестве параметров
Предположим, вам нужна процедура, которая принимает имя любой таблицы базы данных , а затем удаляет эту таблицу из вашей схемы . Вы должны построить строку с оператором , который включает имена объектов , затем использовать EXECUTE IMMEDIATE для выполнения оператора:
CREATE TABLE employees_temp AS SELECT last_name FROM employees;
CREATE PROCEDURE drop_table (table_name IN VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
END;
/
Используйте конкатенацию для построения строки, {{ 1}} вместо того, чтобы пытаться передать имя таблицы в качестве переменной связывания с помощью предложения USING.
Кроме того, если вам нужно вызвать процедуру , имя которой неизвестно до времени выполнения , вы можете передать параметр , идентифицирующий процедуру. Для примера следующая процедура может вызвать другую процедуру (drop_table), указав имя процедуры при выполнении .
CREATE PROCEDURE run_proc (proc_name IN VARCHAR2, table_name IN VARCHAR2) ASBEGIN
EXECUTE IMMEDIATE 'CALL "' || proc_name || '" ( :proc_name )' using table_name;
END;
/
Если вы хотите удалить таблицу с помощью процедуры drop_table, вы можете запустить процедуру следующим образом. Обратите внимание, что имя процедуры пишется с заглавной буквы.
CREATE TABLE employees_temp AS SELECT last_name FROM employees;
BEGIN
run_proc('DROP_TABLE', 'employees_temp');
END;
/
Используйте оператор выполнить немедленно
для выполнения DDL внутри PL / SQL.
create procedure RebuildIndex(index_name varchar2) as
begin
execute immediate 'alter index ' || index_name || ' rebuild';
end;
Я тестировал этот код; оно работает.