Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как внести данные в таблицу внутри EXECUTE IMMEDIATE ? [D5, Oracle]


Termik ©   (2002-06-07 12:08:00) 

Мастера, помогите !
Формирую динамический запрос вида: SQL_Str := "SELECT MyFunc(Param) FROM dual".
В функции MyFun есть, в частности, оператор "INSERT ....".
Далее, пытаюсь выполнить: EXECUTE IMMEDIATE SQL_Str INTO My_Result.
В ответ на попытку выполнения сервер выдает ответ: "Невозможно выполнение оператора DML внутри запроса."
Как можно это обойти ?


MishGan`   (2002-06-07 14:52:00) [1]

>>А переменная i вернется ?
Над этим я особо не думал. Но могу предложить завести временную таблицу из двух полей (id_транзакции и значения) и через нее передавать результат. Это первое, что приходит в голову.

Пример:
create global temporary table temp_table (transaction_id varchar2(100), value int);

А вставлять так (через EXECUTE IMMEDIATE):
insert into temp_table values (dbms_transaction.local_transaction_id,1);
Ну и читать потом значение из основного кода.

Повторюсь, что это первое, что пришло в голову. Уверен, что есть решение лучше.




Termik   (2002-06-07 14:32:00) [2]

А переменная i вернется ?


Termik   (2002-06-07 14:31:00) [3]

>MishGan"
СЛУШАЙ, А ТЫ, НАВЕРНОЕ, ПРАВ ! Сейчас попробую и напишу о результатх.


MishGan`   (2002-06-07 14:14:00) [4]

А почему так нельзя, не пойму:

SQL_Str := "DECLARE i int; BEGIN i:="||MyFunct||"; END;";


Termik   (2002-06-07 14:10:00) [5]

>MishGan"
Нет, отдельные части составной функции MyFunc берутся из разных записей сторонней таблицы (она, в принципе, не имеет отношения к делу). Я немого неправильно написал строку формирования динамического SQL. Она выглядит так:
SQL_Str := "SELECT "|| MyFunc ||" FROM dual".
Ну вот, MyFunc формируется динамически. Затем и нужен Execute Immediate, чтобы ее выполнить и вернуть результат.
Поэтому так, как ты написал, работать не будет.


MishGan`   (2002-06-07 14:07:00) [6]

Termik, может быть так подойдет для решения задачи:

SQL> create or replace function f1 return int is
2 begin
3 return(1);
4 end;
5 /

Function created.

SQL> begin
2 execute immediate "DECLARE i int; BEGIN i:=f1; END;";
3 end;
4 /

PL/SQL procedure successfully completed.

SQL>


MishGan`   (2002-06-07 13:53:00) [7]

Как понять динамечески?
Т.е. пользователь в процессе работы выполняет: create or replace function...?


Termik   (2002-06-07 13:18:00) [8]

>MishGan" Дело в том, что функция My Func формируется динамически, поэтому так работать не будет.


MishGan`   (2002-06-07 13:13:00) [9]

Хранимые функции в ORACLE могут вызываться двумя способами
1) В предложении SQL (т.е. как в примере у автора вопроса)
SELECT MyFunc(Param) FROM dual
В этом случае функция должная иметь ряд ограничений, таких как отсутствие внутри себя операторов DML (insert, update, deelte), запрещается использовать пакет DBMS_SQL и т.д.
2) В коде PL/SQL. Здесь вышеперечисленных ограничений не накладывается.
DECLARE
RES INT;
BEGIN
RES:=MyFunc(Param);
END;

Так что думаю здесь все решаемо.


Jim   (2002-06-07 12:39:00) [10]

Попробуй DBMS_SQL...


petr_v_a   (2002-06-07 12:39:00) [11]

Никак. Функция, вызываемая в select, не может модифицировать данные.


Johnny Smith   (2002-06-07 12:38:00) [12]

Ситуация здесь такая.
В принципе, выполнять Insert, Update, Delete в функциях нельзя. Для этого должны использоваться хранимые процедуры.
Однако...
Если у тебя Оракл 8i (а у тебя, похоже, именно он или "девятка"), то если ты используешь функцию с DML внутри не в Select"е, а в Insert"e или Update"е, то ошибки не возникнет (если Insert или Update относятся к другой таблице).
В твоем же случае лучше все-таки запихнуть Dynamic SQL в процедуру.


Наверх

Титульная страница Поиск, карта сайта Написать письмо