Разрешено ли использование SELECT внутри конвейерной табличной функции PL/SQL?

Документы для конвейерных функций говорят, что DML не разрешен, когда они используются в операторе SQL (обычно SELECT), и в большинстве примеров конвейерные функции используются для генерации или преобразования данных (принимая кастора в качестве параметра), но не выдают никаких операторов DML.

Теперь технически возможно использовать SELECT без каких-либо ошибок от Oracle ( ORA 14551 не произойдет). Тем не менее, у меня есть опыт воспроизводимого странного поведения избранных; даже если PRAGMA AUTONOMOUS_TRANSACTION не используются, строки, извлеченные SELECT кажется, не всегда принимая во внимание текущую локальную транзакцию, что для меня похоже на ошибку. Еще более тревожным является тот факт, что при использовании распределенной транзакции (например, через ORAMTS вместо локальной транзакции) используется транзакция.

Редактировать: Оказывается, странный эффект, похоже, связан с некоторыми операторами WITH в запросе, которые иногда работают, а иногда нет (в зависимости от текущего настроения оптимизатора Oracle, по крайней мере, в 10g). В некоторых случаях я получаю ORA-32036, но опять же это не происходит, вообще не меняя код. Теперь это выглядит так, как будто запросы, которые иногда терпят неудачу с ORA-32036, являются теми, которые также не в состоянии использовать правильную транзакцию, и это может быть не связано с конвейерной функцией.

Итак, мои конкретные вопросы:

  • Есть ли, желательно официальное, заявление SELECTРазрешены ли в конвейерной таблице функции и каков их транзакционный контекст?

  • Есть ли другой способ модуляции часто используемых запросов, которые могут быть использованы в операторах SQL (так же, как табличные функции могут с TABLE())?

  • Кто-нибудь также испытывал такое поведение и, возможно, знает об этом больше? Я изучал металинк, но, к сожалению, не нашел ничего конкретного по этой теме.

1 ответ

Решение
  1. обычно ограничения DML касаются только операторов модификации (UPDATE, DELETE ...), поэтому SELECT должен быть в порядке. Я постараюсь найти конкретное утверждение от Oracle.

  2. Представления будут вашим первым инструментом для модульной часто используемых запросов.

  3. Функции имеют недостаток в представлениях: если они вызываются из другого SELECT, они не выполняются в тот же момент времени, что и основной SELECT. Каждый вызов SELECT является непротиворечивым, но поскольку SELECT находятся в коде функции, а не в основном SQL, вы можете возвращать противоречивые результаты. Это невозможно с представлениями и дополнительным выбором: если большой оператор вызывает представление, представление строится в тот же момент времени, что и основной запрос.

Обновление: относительно вашего комментария о параметризованных запросах

Вы можете создавать параметризованные представления, то есть представления, которые зависят от переменных, установленных перед выполнением. Вот пример на AskTom, показывающий, как вы могли бы сделать это с userenv('client_info') или же dbms_session.set_context,

Другие вопросы по тегам