powered by simpleCommunicator - 2.0.44     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вызов хранимой функции
9 сообщений из 9, страница 1 из 1
Вызов хранимой функции
    #32064055
Korm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помогите, кто знаком с такой проблемой....
Сервер 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.
CREATE OR REPLACE FUNCTION INET.INET_NEWORDER(IDCLIENTX IN NUMBER, DATEFROMX IN DATE, ORDERNOX IN VARCHAR2) RETURN NUMBER
IS
   IDORDERSX NUMBER;
BEGIN

  SELECT COUNT(*) INTO IDORDERSX FROM INET.ORDERS WHERE (INET.ORDERS.ORDERNO=ORDERNOX);
  IF (IDORDERSX =  0 ) THEN
  BEGIN
    SELECT (NVL(MAX(IDORDERS), 0 )+ 1 ) INTO IDORDERSX FROM INET.ORDERS;
    INSERT INTO INET.ORDERS (IDORDERS, DATEFROM, IDCLIENT, ORDERNO) VALUES
       (IDORDERSX, DATEFROMX, IDCLIENTX, ORDERNOX);
    COMMIT;
    RETURN IDORDERSX;
    EXCEPTION
      WHEN OTHERS THEN
      BEGIN
        ROLLBACK;
         RETURN  0 ;
      END;
  END;
  ELSE
    RETURN - 1 ;  
  END IF;
END INET_NEWORDER;


Она идеально запускается и работает следующим блоком:
Код: plaintext
1.
2.
3.
begin
  dbms_output.put_line(TO_CHAR (inet_neworder( 100 , to_date( 23112001 ,'dd.mm.yyyy'), '453543a54')));
end;


Однако ничего не возвращает (NULL) при использовании в операторе select:
Код: plaintext
select inet.inet_neworder( 100 , to_date( 23112001 ,'dd.mm.yyyy'), '453543a54') id from dual;
хотя пустое значение логикой не предусмотрено (можете оценить код).

При этом, если в хранимой функции удалить строки INSERT....COMMIT , то и вызов с помощью select отрабатывает нормально.

Где я оступился?
...
Рейтинг: 0 / 0
Вызов хранимой функции
    #32064061
Korm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Забыл уточнить:
мне надо по-зарез вызов через select .

Чтобы легче разобраться, дополню, что суть функции заключается в добавлении записи в таблицу и возвратом ID этой записи, либо кода ошибки
...
Рейтинг: 0 / 0
Вызов хранимой функции
    #32064087
mms
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
mms
Гость
Похоже тебе надо прописать в функции прагму:
чтот-то типа
PRAGMA RESTRICT_REFERENCES(...), где именно прописывают и какие параметры передавать не помню, посмотри в документации.
...
Рейтинг: 0 / 0
Вызов хранимой функции
    #32064140
none
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Была у меня подобная ерунда.
Проблема в том, что в функции стояла конструкция SELECT ... INTO, которая не возвращала ничего. Естественно по всем канонам должен произойти эксепшн NO_DATA_FOUND. Он видать и происходил, но в клиентское приложение ошибка не возвращалась, а возвращался NULL (так, как будто функция вертула NULL). Но у тебя есть блок обработки исключений, тогда почему?

Далее, если это функция, которая предполагает вызавов SQL-ом (а не PL/SQL), то она не может содержать DML операций (в твоем случае INSERT, COMMIT, ROLLBACK). Такие функции могут быть валидними, если ты укажешь прагму PRAGMA AUTONOMOUS_TRANSACTION. То есть функия становится Автономной Транзакцией. (Одно из применений, которое мне очень понравилось - если необходимо НЕ завершать/продолжать транзакцию в которой есть DDL операрации. Они в этом случае помещаются в автономную процедуру).

Удачи!
...
Рейтинг: 0 / 0
Вызов хранимой функции
    #32064147
none
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще раз внимательнее оценил твой пример. В догонку к сказанному: уверен что первая DML операция INSERT вызавает исключение типа: Не могу отработать DML опрацию, если меня вызвали СЕЛЕКТОМ. По идее далее прыгаем в блок исключений и возвращаем 0. А почемуже тогда NULL. Фак, не знаю! Может это такой хитрый эксепш, который не отлавливается? И оракл возвращает NULL.
...
Рейтинг: 0 / 0
Вызов хранимой функции
    #32064149
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такое понятие как уровень строгости функции, использующихся в SQL запросах. Обязательным уровнем строгости для всех функций является уровень WNDS, который гласит: Функция не имеет права модифицировать
таблицы базы данных(при помощи операторов DML).
DML, как известно это insert, update, delete.
Вот вам и причина.
...
Рейтинг: 0 / 0
Вызов хранимой функции
    #32064402
nik_x
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Согласен с softbuilder@inbox.ru, дополняю: подобные вещи нельзя делать в триггерах и функциях. Для этих целей есть процедуры.
...
Рейтинг: 0 / 0
Вызов хранимой функции
    #32064450
babay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Re: softbuilder@inbox.ru
> Есть такое понятие как уровень строгости функции,
> использующихся в SQL запросах. Обязательным уровнем
> строгости для всех функций является уровень WNDS,
> который гласит: Функция не имеет права
> модифицировать таблицы базы данных (при помощи
> операторов DML).

Парите и лечите :-)
Внутри блоков PL/SQL поддерживаются команды SQL, такие как SELECT, INSERT, UPDATE, DELETE, COMMIT, ROLLBACK, SAVEPOINT . Если бы это было не так то и вызов функции через dbms_output.put_line приводил бы к ошибке. А вот внутри select'а использование commit и rollback недопустимо.
...
Рейтинг: 0 / 0
Вызов хранимой функции
    #32064465
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Парите и лечите :-)
Внутри блоков 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(анонимном или именованом).
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вызов хранимой функции
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]