|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
Помогите, кто знаком с такой проблемой.... Сервер Oracle 8i имеется хранимая функция след. вида: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Она идеально запускается и работает следующим блоком: Код: plaintext 1. 2. 3.
Однако ничего не возвращает (NULL) при использовании в операторе select: Код: plaintext
При этом, если в хранимой функции удалить строки INSERT....COMMIT , то и вызов с помощью select отрабатывает нормально. Где я оступился? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2002, 14:23 |
|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
Забыл уточнить: мне надо по-зарез вызов через select . Чтобы легче разобраться, дополню, что суть функции заключается в добавлении записи в таблицу и возвратом ID этой записи, либо кода ошибки ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2002, 14:28 |
|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
Похоже тебе надо прописать в функции прагму: чтот-то типа PRAGMA RESTRICT_REFERENCES(...), где именно прописывают и какие параметры передавать не помню, посмотри в документации. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2002, 14:42 |
|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
Была у меня подобная ерунда. Проблема в том, что в функции стояла конструкция SELECT ... INTO, которая не возвращала ничего. Естественно по всем канонам должен произойти эксепшн NO_DATA_FOUND. Он видать и происходил, но в клиентское приложение ошибка не возвращалась, а возвращался NULL (так, как будто функция вертула NULL). Но у тебя есть блок обработки исключений, тогда почему? Далее, если это функция, которая предполагает вызавов SQL-ом (а не PL/SQL), то она не может содержать DML операций (в твоем случае INSERT, COMMIT, ROLLBACK). Такие функции могут быть валидними, если ты укажешь прагму PRAGMA AUTONOMOUS_TRANSACTION. То есть функия становится Автономной Транзакцией. (Одно из применений, которое мне очень понравилось - если необходимо НЕ завершать/продолжать транзакцию в которой есть DDL операрации. Они в этом случае помещаются в автономную процедуру). Удачи! ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2002, 15:39 |
|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
Еще раз внимательнее оценил твой пример. В догонку к сказанному: уверен что первая DML операция INSERT вызавает исключение типа: Не могу отработать DML опрацию, если меня вызвали СЕЛЕКТОМ. По идее далее прыгаем в блок исключений и возвращаем 0. А почемуже тогда NULL. Фак, не знаю! Может это такой хитрый эксепш, который не отлавливается? И оракл возвращает NULL. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2002, 15:48 |
|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
Есть такое понятие как уровень строгости функции, использующихся в SQL запросах. Обязательным уровнем строгости для всех функций является уровень WNDS, который гласит: Функция не имеет права модифицировать таблицы базы данных(при помощи операторов DML). DML, как известно это insert, update, delete. Вот вам и причина. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2002, 15:58 |
|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
Согласен с softbuilder@inbox.ru, дополняю: подобные вещи нельзя делать в триггерах и функциях. Для этих целей есть процедуры. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2002, 07:01 |
|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
Re: softbuilder@inbox.ru > Есть такое понятие как уровень строгости функции, > использующихся в SQL запросах. Обязательным уровнем > строгости для всех функций является уровень WNDS, > который гласит: Функция не имеет права > модифицировать таблицы базы данных (при помощи > операторов DML). Парите и лечите :-) Внутри блоков PL/SQL поддерживаются команды SQL, такие как SELECT, INSERT, UPDATE, DELETE, COMMIT, ROLLBACK, SAVEPOINT . Если бы это было не так то и вызов функции через dbms_output.put_line приводил бы к ошибке. А вот внутри select'а использование commit и rollback недопустимо. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2002, 11:00 |
|
Вызов хранимой функции
|
|||
---|---|---|---|
#18+
"Парите и лечите :-) Внутри блоков PL/SQL поддерживаются команды SQL, такие как SELECT, INSERT, UPDATE, DELETE, COMMIT, ROLLBACK, SAVEPOINT. Если бы это было не так то и вызов функции через dbms_output.put_line приводил бы к ошибке. А вот внутри select'а использование commit и rollback недопустимо." Для тех кто не понял- обьясняю еще раз. Функцию можно вызывать: 1) непосредственно в PL/SQL блоке cnt_ord NUMBER(16); begin cnt_ord:= my_function(...) end; 2) в SQL запросе - select my_function(...) from .... На использование функий в SQL запросах(т.е во втором случае) накладываются дополнительные ограничения. В частности уровень строгости WNPS(см выше) Приведённые вами пример:"вызов функции через dbms_output.put_line" - абсолютно некорректный: 1) put_line - является процедурой procedure put_line(a varchar2); pragma restrict_references(put_line,WNDS,RNDS); procedure put_line(a number); pragma restrict_references(put_line,WNDS,RNDS); и не может быть использована в SQL запросе 2) Вызов dbms_output.put_line может производится только в блоке PL/SQL(анонимном или именованом). ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2002, 11:53 |
|
|
start [/forum/topic.php?fid=52&fpage=2835&tid=1992820]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
49ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
51ms |
get tp. blocked users: |
2ms |
others: | 282ms |
total: | 431ms |
0 / 0 |