Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / обращение к pipelined функции Oracle11g из jdbc / 25 сообщений из 41, страница 1 из 2
28.12.2015, 17:01
    #39139514
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Добрый день, уважаемые форумчане.

Подскажите пожалуйста, можно ли обратиться к pipelined функции Oracle11g через jdbc с таким синтаксисом:
Код: plaintext
1.
2.
3.
 String strCall = "{?= call rowtypes.f_char() }";
 calWork = cnn.prepareCall(strCall);
 calWork.registerOutParameter(1, OracleTypes.PLSQL_INDEX_TABLE);
 calWork.execute();

При помощи такого синтаксиса -
Код: plaintext
1.
2.
  String strSql = "select * from table(rowtypes.f_pipe)";
  OracleStatement stmt = (OracleStatement) cnn.createStatement();
  OracleResultSet rsWork = (OracleResultSet) stmt.executeQuery(strSql);
все работает, но хотелось бы использовать call.

Версия Oracle 11.2.0.3, версия JDK = 1.8, драйвер ojdbc6.jar

Скрипт пакета Oracle:
Код: 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 package rowtypes is
  cursor cur is
    select * from employees;
  type tbl is table of cur%rowtype;
  function f_pipe return tbl
    pipelined;
  function f_char return varchar2;
end;
/

create or replace package body rowtypes is
  function f_char return varchar2 is
  begin
    return 'TEXT';
  end; 
  function f_pipe return tbl pipelined is
  begin
    for rec in cur loop 
      pipe row(rec);
    end loop;
  end;
end;
/

Текст класса Java прилагается.

Заранее спасибо за ответ.
...
Рейтинг: 0 / 0
28.12.2015, 17:12
    #39139527
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Думаю, что нет.

Да и не понятно зачем. AFAIK INDEX TABLE это совсем не Ref Cursor, а значительно более худшая (менее гибкая) штука. Т.ч. смысл ломать относительно эффективный pipelined и получать на выходе банальный array - не понятен.
...
Рейтинг: 0 / 0
28.12.2015, 17:14
    #39139528
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Можно в анонимном pl/sql блоке зафетчить SELECT <список полей> FROM ... в массив. Только нафига?
...
Рейтинг: 0 / 0
29.12.2015, 11:27
    #39139883
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Добрый день, уважаемые форумчане.

Leonid KudryavtsevДумаю, что нет.

Да и не понятно зачем. AFAIK INDEX TABLE это совсем не Ref Cursor, а значительно более худшая (менее гибкая) штука. Т.ч. смысл ломать относительно эффективный pipelined и получать на выходе банальный array - не понятен.

А какой тип надо ставить для выходного параметра pipelined-функции?
Пробовал так -

Код: plaintext
calWork.registerOutParameter(1, OracleTypes.CURSOR);



Получил такой ответ -
Код: plaintext
1.
2.
3.
4.
java.sql.SQLException: ORA-06550: line 5, column 12:
PLS-00653: aggregate/table functions are not allowed in PL/SQL scope
ORA-06550: line 1, column 22:


Также пробовал и OracleTypes.STRUCT и OracleTypes.ARRAY - всегда получал сообщение об ошибке.

Попутно вопрос - как можно получить метаданные о типе возвращаемого функцией значения?

Заранее спасибо.

Заранее спасибо.
...
Рейтинг: 0 / 0
29.12.2015, 11:31
    #39139888
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
МурзикА какой тип надо ставить для выходного параметра pipelined-функции?
вы же написали что всё работает в первом варианте?
МурзикПопутно вопрос - как можно получить метаданные о типе возвращаемого функцией значения?
это ненужно.
Это маппинг. Т.е. статика и проектирование.
При смене даговора по API переписывается маппинг (код)
......
Универсальность - враг хорошего. Почему вообще пипелине функция? Не смогли запрос сложный сделать?
...
Рейтинг: 0 / 0
29.12.2015, 11:56
    #39139912
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Добрый день.

Petro123МурзикА какой тип надо ставить для выходного параметра pipelined-функции?
вы же написали что всё работает в первом варианте?
МурзикПопутно вопрос - как можно получить метаданные о типе возвращаемого функцией значения?
это ненужно.
Это маппинг. Т.е. статика и проектирование.
При смене даговора по API переписывается маппинг (код)
......
Универсальность - враг хорошего. Почему вообще пипелине функция? Не смогли запрос сложный сделать?

Как я понял, работать с pipeline-функцией из jdbc можно только через select * from table(имя_pipelined_функции) ?

pipeline функция нужна для вывода инфы из коллекции, которая не объявлена в базе.

Кстати о метаданных -
strCall = "{?= call rowtypes.f_pipe}";
calWork = cnn.prepareCall(strCall);
rsMeta = (OracleResultSetMetaData) calWork.getMetaData();
System.out.println("Arguments pipe=" + rsMeta.getColumnCount());

возвращает NullPointerException.
Правильно ли я понимаю, что getMetaData() работает только для ResultSet ?

Заранее спасибо.
...
Рейтинг: 0 / 0
29.12.2015, 11:59
    #39139916
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Мурзикpipeline функция нужна для вывода инфы из коллекции, которая не объявлена в базе.
переведи:
функция в БД нужна чтобы вывести то, что не в БД?
...
Рейтинг: 0 / 0
29.12.2015, 12:06
    #39139925
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Мурзик, в данном случае, у тебя совершенно НОРМАЛЬНЫЙ код, правда с select'ом. Нафига возникает желание переписать его на call не понятно.

Если очень хочется и нужно (например юзаешь универсальную библиотеку, которая понимает только входной текст (pl/sql анонимный блок) и умеет использовать только java.sql.PreparedCall), то, конечно, всегда можно. Но если реальных причин нет, то не нужно городить сложности и находить массу проблем на ровном месте.

МурзикПопутно вопрос - как можно получить метаданные о типе возвращаемого функцией значения?

1) JAVA:

В данном, конкретном случае, у тебя не функция, а нормальный селект.

Т.ч., так же, как и для Select'а. Элементарно через ResultSet.getMetaData()

2) Oracle
Или посмотреть в Oracle таблицах с матаописаниями. Но этот вопрос лучше задать на форуме Oracle.

Наверное в табличках ALL_PROCEDURES (USER...), ALL_ARGUMENTS (USER...)

Ссылка на оригинальную доку гуглится за 15 сек.
...
Рейтинг: 0 / 0
29.12.2015, 12:12
    #39139938
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
МурзикКак я понял, работать с pipeline-функцией из jdbc можно только через select * from table(имя_pipelined_функции) ?

А причем тут JDBC ? Кто-то знает другие возможности работать с pipeline-функциями ?

Мурзикpipeline функция нужна для вывода инфы из коллекции, которая не объявлена в базе.

Ну так сделайте нормальную ф-цию (не пайплинед) которая возвращает собственно коллекцию.

Или, банально, сделайте коллекцию паблик и прямо ее и бери из пакета (подозреваю, она в пакете объявлена) через анонимный pl/sql.
...
Рейтинг: 0 / 0
29.12.2015, 12:15
    #39139940
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Leonid KudryavtsevНаверное в табличках ALL_PROCEDURES
причём права должны быть даны от админов на эту Мету-инфу
...
Рейтинг: 0 / 0
29.12.2015, 12:23
    #39139955
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Мурзикpipeline функция нужна для вывода инфы из коллекции, которая не объявлена в базе.
странно вообще употребление слова коллекция без ОРМ, но с JDBC.
По умолчанию у JDBC набор строк, объект ResultSet.
...
Рейтинг: 0 / 0
29.12.2015, 14:42
    #39140068
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Leonid KudryavtsevМурзик, в данном случае, у тебя совершенно НОРМАЛЬНЫЙ код, правда с select'ом. Нафига возникает желание переписать его на call не понятно.

Если очень хочется и нужно (например юзаешь универсальную библиотеку, которая понимает только входной текст (pl/sql анонимный блок) и умеет использовать только java.sql.PreparedCall), то, конечно, всегда можно. Но если реальных причин нет, то не нужно городить сложности и находить массу проблем на ровном месте.



Понял, больше не буду мучать бедный
Код: plaintext
CallableStatement
, удовлетворюсь
Код: plaintext
OracleStatement

Leonid Kudryavtsev2) Oracle
Или посмотреть в Oracle таблицах с матаописаниями. Но этот вопрос лучше задать на форуме Oracle.

Наверное в табличках ALL_PROCEDURES (USER...), ALL_ARGUMENTS (USER...)

Ссылка на оригинальную доку гуглится за 15 сек.

Эти представления словаря мне известны, я хотел бы понять, как Oracle-типы видятся из java.
...
Рейтинг: 0 / 0
29.12.2015, 14:50
    #39140074
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Petro123переведи:
функция в БД нужна чтобы вывести то, что не в БД?

Я хочу использовать коллекцию Oracle (ассоциативный массив или index by таблицу) в качестве временного источника-приемника данных.
Каждая из колонок этой коллекции будет заполняться отдельным selectОм и потом выводится как результат работы функции.
Можно, конечно, использовать какой-нибудь UNION ALL, но общий select в этом случае будет просто неприличных размеров.
Пример задачи - расчет 16-го счета.
Почему не хочу объявлять коллекцию на уровне базы - ее структура может измениться (например, добавятся новые колонки) и придется тогда перекомпилировать все зависящие от этого типа пакеты.
Опять же - невозможно объявить index by таблицу на уровне базы данных, а ключи по varchar2 типу или отрицательные ключи возможны только в этой коллекции.
...
Рейтинг: 0 / 0
29.12.2015, 15:23
    #39140106
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Мурзик,
у меня впечатление, что ты используешь БД нетрадиционным сексуальным образом.
МурзикПример задачи - расчет 16-го счета.
эта? Приведи пример задачи
http://www.buhsoft.ru/forums/showthread.php?t=9420
ЗЫ.
Если у тебя нет модели для БД, то зачем тебе вообще БД?
Делай всё в оперативке в Java по ООП.
IMHO
Мурзикв качестве временного источника-приемника данных.
т.е. в анонимном блоке ты записал в оракл (в таблицу?) и потом в этом же коннекте прочитал?
Pipeline функуция просто перекидывает данные из таблицы (кортеж) в твою структуру-record созданную руками.
...
Рейтинг: 0 / 0
29.12.2015, 15:33
    #39140118
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Мурзик, я так понял, что-то типа cross tab отчетов на pipelined функциях?
...
Рейтинг: 0 / 0
29.12.2015, 16:22
    #39140160
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Оказалось, что pipelined-функции не используют index-by коллекции :(


МурзикЯ хочу использовать коллекцию Oracle (ассоциативный массив или index by таблицу) в качестве временного источника-приемника данных.


Сделал так -
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
create or replace package rowtypes is
  cursor cur is
    select * from employees;
  type tp_row is record(
    account  varchar2(10),
    sum_nach number(10, 2),
    sum_upl  number(10, 2));
  type tp_tbl is table of tp_row;

  function f_pipe return tp_tbl
    pipelined;
  function f_char return varchar2;
end;
/

create or replace package body rowtypes is
  function f_char return varchar2 is
  begin
    return 'TEXT';
  end;
  function f_pipe return tp_tbl
    pipelined is
    v_tbl  tp_tbl;
    type tp_tbl_index is table of varchar2(10) index by pls_integer;
    v_tbl_index tp_tbl_index;
    v_indx varchar2(10);
    v_row  tp_row;
  begin
    select * bulk collect
      into v_tbl
      from (select 1006 f_accoun, 0 f_nach, 0 f_upl
              from dual
            union all
            select 1008, 0, 0 from dual) v;
    v_indx:=v_tbl.first;
    while v_indx is not null loop
          v_tbl_index(v_tbl(v_indx).account):=v_indx;
          v_indx:=v_tbl.next(v_indx);  
    end loop;            
    v_tbl(v_tbl_index('1006')).sum_nach := 106.01;
    v_tbl(v_tbl_index('1008')).sum_nach := 108.02;
    v_tbl(v_tbl_index('1006')).sum_upl := 96.01;
    v_tbl(v_tbl_index('1008')).sum_upl := 98.01;
    v_indx := v_tbl.first;
    while (v_indx is not null) loop
      v_row := v_tbl(v_indx);
      pipe row(v_row);
      v_indx := v_tbl.next(v_indx);
    end loop;
    dbms_session.free_unused_user_memory;
    return;
  end;
end;
/
...
Рейтинг: 0 / 0
29.12.2015, 16:31
    #39140165
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Petro123Мурзик,
у меня впечатление, что ты используешь БД нетрадиционным сексуальным образом.
МурзикПример задачи - расчет 16-го счета.
эта? Приведи пример задачи
http://www.buhsoft.ru/forums/showthread.php?t=9420
ЗЫ.
Если у тебя нет модели для БД, то зачем тебе вообще БД?
Делай всё в оперативке в Java по ООП.
IMHO
Мурзикв качестве временного источника-приемника данных.
т.е. в анонимном блоке ты записал в оракл (в таблицу?) и потом в этом же коннекте прочитал?
Pipeline функуция просто перекидывает данные из таблицы (кортеж) в твою структуру-record созданную руками.

Добрый день, еще раз, уважаемые форумчане -
Именно так -
Код: plaintext
1.
2.
3.
Сумма отклонений = Сальдо по дебету 16-го счета на начало месяца
+ Оборот по дебету 16-го счета за месяц х Оборот по кредиту 10-го (41) счета за месяц

Сальдо по дебету 10-го (41) счета на начало месяца + Оборот по дебету 10-го (41) счета за месяц 


Правда, считал это еще на Oracle 8 и не знал я тогда еще никаких коллекций, а может их еще и не было....
Посему приходилось все эти колонки вытаскивать разными selectАми, потом их UNION ALL и потом GROUP BY.

Пользоатели получали такой грид с этими числами, смотрели все ли там правильно и потом забрасывали в базу, тут же формировались проводки по 16-му.
То есть сперва надо было получить грид без записи в базу, а "по утверждению оного" формировать проводки.
Опять же в Дебете по 16-му должны были быть отражены те суммы, которые еще не легли в проводках на 16-й счет :)
Каждый месяц считалось по-разному.
Но это уже без отношения к Java.
...
Рейтинг: 0 / 0
29.12.2015, 16:31
    #39140166
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Leonid Kudryavtsev,
что-то типа того....
...
Рейтинг: 0 / 0
29.12.2015, 16:57
    #39140186
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
МурзикПравда, считал это еще на Oracle 8 и не знал я тогда еще никаких коллекций, а может их еще и не было....
Посему приходилось все эти колонки вытаскивать разными selectАми, потом их UNION ALL и потом GROUP BY.
не пойму чем у вас счас коллекции помогают?
Есть временная табла на коннект....без записи в БД...своя на каждого юзверя...
...
Рейтинг: 0 / 0
29.12.2015, 17:24
    #39140209
Мурзик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Petro123МурзикПравда, считал это еще на Oracle 8 и не знал я тогда еще никаких коллекций, а может их еще и не было....
Посему приходилось все эти колонки вытаскивать разными selectАми, потом их UNION ALL и потом GROUP BY.
не пойму чем у вас счас коллекции помогают?
Есть временная табла на коннект....без записи в БД...своя на каждого юзверя...

Временная табла в Oracle - это некошерно.
Опять же, возможен вход двух разных людей под однима аккаунтом и т.п.
...
Рейтинг: 0 / 0
29.12.2015, 17:33
    #39140215
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
МурзикВременная табла в Oracle - это некошерно.

======= привел бы ПРИМЕР кода, было бы видно, велосипед или некошерно

Опять же, возможен вход двух разных людей под однима аккаунтом и т.п.

====== странный ты. Это как с одним коннектом Иванов и Петров войдут? Шутка?


есть штатные механизмы Оракла. Ты утверждаешь, что это не кошерно.
Удачи!
...
Рейтинг: 0 / 0
29.12.2015, 18:06
    #39140233
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
"временная табла" это CREATE GLOBAL TEMPORARY TABLE ?

Тогда интересно, что подразумевается под "без записи в БД", "своя на каждого юзверя" ?
...
Рейтинг: 0 / 0
29.12.2015, 18:12
    #39140238
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
To Мурзик:
может попросить модераторов в форум Oracle перенести? Из всего обсуждения, от Java одно название. IMHO
...
Рейтинг: 0 / 0
29.12.2015, 18:27
    #39140252
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Leonid Kudryavtsev,
Раз он не хочет Модель и писать в таблу напр. Входящие, то есть в БД временные таблицы....всякие.
Есть на коннект, есть уровень видимости пакета (как раз для бухов). Есть уровень анонимного блока, функции.
Проще сказать чего там нет)))).
ООП)).
Но он Ооп и не применяет.
...
Рейтинг: 0 / 0
29.12.2015, 18:42
    #39140256
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
обращение к pipelined функции Oracle11g из jdbc
Нифига не понял, что Вы подразумеваете под понятием "временные таблицы" на русском языке. Но не будем разводить холевар ))) на пустом месте.

Я обычно употребляю или "временная таблица" в БД или "массив" в Pl/sql. От того, что Oracle массив назвал TABLE INDEX BY, он таблицей не стал. К тому же, прилагательное TEMPORARY ("временный") с массивом TABLE INDEX BY обычно не употребляется.

Т.ч. назвать массивы (коллекции) - "временные таблицы....всякие... есть уровень видимости пакета". То всяко или "временный" или "пакета". А не то и другое вместе. А лучше прямо сказать "массив" или "коллекция" (последнее наверное правильнее). IMHO

Просто Ваша мысль про временные таблицы, как-то совсем не ясна.

Насколько я понимаю, Мурзик не хочет объекты в БД плодить без лишней надобности, а хочет обойтись только коллекциями в пакетах.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / обращение к pipelined функции Oracle11g из jdbc / 25 сообщений из 41, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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