#sql #oracle #stored-procedures #plsql
#sql #Oracle #хранимые процедуры #plsql
Вопрос:
У меня есть вопрос о возможности. Я создал хранимую процедуру в базе данных Oracle версии 12c. Для запуска требуется один параметр. Чтобы она работала правильно, передайте параметр следующим образом:
EXEC My_Procedure_Name(parameter_value);
И все идет хорошо, выполняя приведенный выше код.
Теперь я собираюсь запускать эту процедуру (фактически приведенный выше код) в течение двух месяцев ежедневно. Поэтому я написал сценарий, подобный этому:
declare stmt varchar2(100);
begin
for i in (days of months)
loop
stmt:='EXEC My_Procedure_Name(parameter_value);';
EXECUTE IMMEDIATE stmt;
commit;
end loop;
end;
Мой вопрос был бы: правильный ли указанный сценарий? И будет ли это работать? Есть ли какие-либо проблемы с моим скриптом?
Спасибо
Ответ №1:
Для вызова процедуры в цикле синтаксис выглядит следующим образом:
begin
for i in 1..5 loop
dbms_output.put_line(i);
end loop;
end;
Я предполагаю, что for i in (days of months)
это псевдокод, и вы на самом деле будете использовать какую-то допустимую конструкцию для удовлетворения ваших требований.
Если вам действительно нужно использовать динамический код, это можно сделать, но обратите внимание, что в PL / SQL нет EXEC
ключевого слова. Вам понадобится что-то вроде:
begin
for i in 1..5 loop
execute immediate 'begin dbms_output.put_line(:i); end;' using i;
end loop;
end;
или
begin
for i in 1..5 loop
execute immediate 'call dbms_output.put_line(:i)' using i;
end loop;
end;
(Обратите внимание, что в PL / SQL есть ;
оператор terminator, а в SQL его нет.)
Как вы можете видеть, динамический код более сложный, поэтому лучше избегать его, если только нет другого варианта.
Комментарии:
1. Это считается отличным решением. Спасибо, Уильям
Ответ №2:
Вместо этого вы можете попробовать приведенный ниже код без использования немедленного выполнения, а просто ссылаясь на переменную цикла —
declare stmt varchar2(100);
begin
for i in (days of months)
loop
My_Procedure_Name(i.parameter_value);
commit;
end loop;
end;