powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Вызвать через jdbc PL/SQL функцию, возвращающую table of record
4 сообщений из 4, страница 1 из 1
Вызвать через jdbc PL/SQL функцию, возвращающую table of record
    #39434552
just_vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть PL/SQL пакет, в нем объявлено:
Код: plsql
1.
type lalala is record

и
Код: plsql
1.
type table_lalala is table of lalala

потом есть PL/SQL функция, которая
Код: plsql
1.
return table_lalala 

и в общем всю эту радость надо суметь вызвать из JDBC. Судя по всему честного варианта вызвать всю эту радость не существует, ибо прямо в доке написано, что Oracle jdbc driver не умеет работать с RECORD TYPE:
http://docs.oracle.com/cd/B28359_01/java.111/b31224/apxref.htm#BABFECBJ PL/SQL TABLE, BOOLEAN, and RECORD Types
It is not feasible for Oracle JDBC drivers to support calling arguments or return values of the PL/SQL RECORD, BOOLEAN, or table with non-scalar element types. However, Oracle JDBC drivers support PL/SQL index-by table of scalar element types.
Но на просторах интернета пишут, что дескать не беда, нужно просто обернуть это SELECT'ом, примерно так:
Код: plsql
1.
SELECT * FROM TABLE (MySuperPLSQLFunction())


И если функция такая, то все замечательно, работает, но беда в том, что у моей процедуры еще есть параметры. Вроде бы кажется, что не беда, давайте я сделаю вот так:
Код: java
1.
2.
3.
4.
5.
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM TABLE (MySuperPLSQLFunction(?,?,?))");
stmt.setString(1, param1);
stmt.setString(2, param2);
stmt.setString(3, param3);
ResultSet rs = stmt.executeQuery();


Но по непонятной причине я всегда получаю пустой ResultSet и у меня нет идей, что с этим делать.

Подскажите, как то можно по нормальному вызвать эту PL/SQL функцию?

ЗЫ: понимаю, что есть еще варианты, о них я знаю, но пока хотелось бы их избежать:
1. Обернуть внутри PL/SQL в функцию, возвращающую sys_refcursor и нормально вызвать ее
2. Использовать обычный Statement, собирать текст запроса как строку, получить уязвимость на SQLInjection и засрать shared pool
...
Рейтинг: 0 / 0
Вызвать через jdbc PL/SQL функцию, возвращающую table of record
    #39434739
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
just_vladimir1. Обернуть внутри PL/SQL в функцию, возвращающую sys_refcursor и нормально вызвать ее

Наверное оптимальный вариант. Ну и не обязательно ф-цию, можно просто анонимный PL/SQL блок

Но нужно аккуратно проверить. Раньше с передачей курсоров были баги. Курсоры открытые на стороне сервера, при закрытие на стороне клиента приводили к ресоурсе лиак. Было это давно, но описание таких багов на металинке встречал.

Как вариант:
1. Разделить массив на несколько и возврашать как OUT параметр процедуры. Т.е. вместо массива структур с полями A,B,C возвращать три массива для каждого поля отдельно. А ни клиенте обратно склеевать (если надо)
2. Попытаться использовать не тип record, а Oralce object'ы. Возможно тогда вернется нормально

IMHO
...
Рейтинг: 0 / 0
Вызвать через jdbc PL/SQL функцию, возвращающую table of record
    #39434825
just_vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,
на самом деле вариант с курсорами уже давным давно работает, в смысле в пакете всегда парно идут функции, одна возвращает табличный тип, вторая sys_refcursor, которая как раз делает select * from table(...), очень хочется вариант с типизированным возвращаемым результатом.
Идея в том, что стандартный способ вызова предполагает, что Java код знает правильные имена функций, правильный порядок и типы параметров и никак статически это соответствие не контролируется, только динамически, в процессе выполнения, это не очень приятно. При этом есть замечательная либа JCodeModel и не менее замечательные таблицы с метаданными в Oracle (ALL_PROCEDURES, ALL_ARGUMENTS, ALL_TYPES и т.д.), дальше идея рождается сама собой, пишем небольшой кодогенератор, который по метаданным создает DAO классы (1 PL/SQL пакет - 1 DAO класс), 1 функция пакета - 1 метод в DAO'шке, соответственно с точки зрения Java кода я получаю статический контроль правильности имени пакета, имени функции и параметров, но остается беда, что на выходе курсор это нечто вроде List<Map<String,Object>>, а хотелось бы List<MyPLSQLRecord> и даже эти DTO'шки не проблема сгенерировать и все вроде хорошо, но вот такая загвоздка в конце, что похоже такие функции в принципе гуманными способами не вызываются...
...
Рейтинг: 0 / 0
Вызвать через jdbc PL/SQL функцию, возвращающую table of record
    #39434849
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
just_vladimir

Не очень понимаю Вашу проблему.
Т.к. анонимный PL/SQL блок "обертку" над ф-цией преобразующий table of в refcursor сделать элементарно.

А метаописание и генерируете DAO от описания исходной ф-ции

Особой разницы по производительности и ресурсам я думаю не будет.

что похоже такие функции в принципе гуманными способами не вызываются
В oracle есть что-то типа ANYTYPE, который вроде и в Java можно получить. Но даже если это и работает, то может оказаться плохо (или не) документировано

На мой взгляд, мучения того не стоят. Проще уж действительно в select обернуть.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Вызвать через jdbc PL/SQL функцию, возвращающую table of record
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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