Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / fetch нескольких полей из sys_refcursor / 21 сообщений из 21, страница 1 из 1
15.11.2019, 18:03
    #39889878
capuzi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
Всем привет.
Есть функция 1 возвращающая sys_refcursor с большим количеством полей.
И есть функция 2, в которой нужно использовать только несколько полей из результирующего курсора функции 1.

Решается через объявление типа, соответствующего результирующему датасету курсора функции 1, но это решение не вполне устраивает (набор полей курсора функции 1 может меняться и отслеживать это никто не будет).

Есть второе решение через перенос курсора в XMLTable и выборку из нее требуемых полей.
Это решение не устраивает начальника.

Больше ничего не могу придумать.
Может быть кто-то знает, есть ли другие способы?
Спасибо.
...
Рейтинг: 0 / 0
15.11.2019, 18:22
    #39889885
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
capuzi,

так не пойдет?
Код: plsql
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.
declare
     c sys_refcursor;
     type number_list is varray(10) of number;
     type string_list is varray(10) of varchar2(4000);
     a number_list;
     b string_list;
     n pls_integer := 1;
begin
     open c for
          select level,
                     to_char(level)
                from dual
                connect by level <= 100;
     loop
          fetch c
                bulk collect into a, b
                limit 10;
          exit when a.count = 0;
          for i in 1..a.count loop
                dbms_output.put_line('a[' || n || '] = ' || a(i) || ', b[' || n || '] = ' || b(i));
                n := n + 1;
          end loop;
     end loop;
     close c;
end;
...
Рейтинг: 0 / 0
15.11.2019, 18:26
    #39889887
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
а, прошу прощения, вам ведь нужно только пара полей из большого списка колонок курсора..
ступил
...
Рейтинг: 0 / 0
15.11.2019, 18:28
    #39889890
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
capuzi
другие способы?
Выборочный define.
иллюстрация
Код: plsql
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.
SQL> declare
  2    rc sys_refcursor;
  3    c int;
  4    col_cnt int;
  5    desc_t  dbms_sql.desc_tab3;
  6    b number;
  7    bi int;
  8  begin
  9    open rc for select 1 as a, level*10 as b, 3 as c from dual connect by level <= 5;
 10    c := dbms_sql.to_cursor_number(rc);
 11    dbms_sql.describe_columns3(c, col_cnt, desc_t);
 12    for i in 1..col_cnt loop
 13      if desc_t(i).col_name = 'B' then
 14        bi := i;
 15        dbms_sql.define_column(c, bi, b);
 16      end if;
 17    end loop;
 18    while dbms_sql.fetch_rows(c) > 0 loop
 19      dbms_sql.column_value(c, bi, b);
 20      dbms_output.put_line(b);
 21    end loop;
 22    dbms_sql.close_cursor(c);
 23  end;
 24  /
10
20
30
40
50

PL/SQL procedure successfully completed.

...
Рейтинг: 0 / 0
15.11.2019, 18:30
    #39889891
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
REFCURSOR --> DBMS_SQL cursor

SY.
...
Рейтинг: 0 / 0
15.11.2019, 19:36
    #39889909
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
можно даже FETCH-ить BULK-ами
Код: plsql
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.
declare
     c sys_refcursor;
     column_1_data dbms_sql.Number_Table;
     column_2_data dbms_sql.Varchar2_Table;
     column_3_data dbms_sql.Date_Table;
     column_1_position integer;
     column_2_position integer;
     column_3_position integer;
     n pls_integer := 1;
     desc_tab dbms_sql.desc_tab;
     cursor_number integer;
     col_cnt integer;
     status integer;
     fetched_count integer;
     fetch_size constant integer := 10;
begin
     open c for
          select level a,
                     level the_column_we_need_1,
                     to_char(level) the_column_we_need_2,
                     sysdate + level the_column_we_need_3,
                     level b
                from dual
                connect by level <= 100;
     cursor_number := dbms_sql.to_cursor_number(c);
     dbms_sql.describe_columns(cursor_number, col_cnt, desc_tab);
     for position in 1..col_cnt loop
          case desc_tab(position).col_name
                when 'THE_COLUMN_WE_NEED_1' then
                     column_1_position := position;
                when 'THE_COLUMN_WE_NEED_2' then
                     column_2_position := position;
                when 'THE_COLUMN_WE_NEED_3' then
                     column_3_position := position;
                else
                     continue;
          end case;
     end loop;
     dbms_sql.define_array(cursor_number, column_1_position, column_1_data, fetch_size, 1);
     dbms_sql.define_array(cursor_number, column_2_position, column_2_data, fetch_size, 1);
     dbms_sql.define_array(cursor_number, column_3_position, column_3_data, fetch_size, 1);
     loop
          fetched_count := dbms_sql.fetch_rows(cursor_number);
          dbms_sql.column_value(cursor_number, column_1_position, column_1_data);
          dbms_sql.column_value(cursor_number, column_2_position, column_2_data);
          dbms_sql.column_value(cursor_number, column_3_position, column_3_data);
          for i in 1..fetched_count loop
                dbms_output.put_line('THE_COLUMN_WE_NEED_1[' || n || '] = ' || column_1_data(i) || ', THE_COLUMN_WE_NEED_2[' || n || '] = ' || column_2_data(i) || ', THE_COLUMN_WE_NEED_3[' || n || '] = ' || column_3_data(i));
                n := n + 1;
          end loop;
          exit when fetched_count < fetch_size;
     end loop;
     dbms_sql.close_cursor(cursor_number);
end;

...
Рейтинг: 0 / 0
16.11.2019, 08:21
    #39889984
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
--Eugene--
можно даже FETCH-ить BULK-ами
Ученик довольно сообразительный.
...
Рейтинг: 0 / 0
19.11.2019, 16:57
    #39891221
роман23t
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
--Eugene--
[spoiler можно даже FETCH-ить BULK-ами]

Только вывод подкорректировать, а то с толку немного сбило, что первые 10 записей выводятся зациклено


Код: plsql
1.
for i in 1..fetched_count loop



поменять на

Код: plsql
1.
for i in n..n + fetched_count - 1 loop
...
Рейтинг: 0 / 0
19.11.2019, 17:38
    #39891254
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
а как насчет Pipeline
...
Рейтинг: 0 / 0
19.11.2019, 17:50
    #39891266
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
andreymx
а как насчет Pipeline
А ты развей свою мысль.
...
Рейтинг: 0 / 0
23.11.2019, 06:08
    #39893275
capuzi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
вот тоже интересно, в pipeline можно профетчить несколько полей курсора?
...
Рейтинг: 0 / 0
23.11.2019, 07:12
    #39893280
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
capuzi
вот тоже интересно, в pipeline можно профетчить несколько полей курсора?
Откуда сомнения?
...
Рейтинг: 0 / 0
25.11.2019, 16:15
    #39894067
capuzi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
Elic
Откуда сомнения?


вопрос в том, как для курсора с неизвестным набором полей объявить переменную с типом курсор%rowtype, чтобы использовать pipe row(переменная)?

dbms_sql в принципе всем устроил, но раз речь зашла о pipeline, то интересно есть ли такая возможность..
...
Рейтинг: 0 / 0
25.11.2019, 16:37
    #39894077
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
capuzi
вопрос в том, как для курсора с неизвестным набором полей объявить переменную с типом курсор%rowtype, чтобы использовать pipe row(переменная)?
Странный вопрос. Зачем? Pipe не может выплюнуть неизвестное. Но разве тебе это надо? Тебе же нужна известная тебе часть. Вот её и декларируй.
...
Рейтинг: 0 / 0
25.11.2019, 16:41
    #39894081
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
Elic
Pipe не может выплюнуть неизвестное.

Вообще-то может... если неизвестное становится известным в момент парсинга, ессно.
...
Рейтинг: 0 / 0
25.11.2019, 17:06
    #39894096
capuzi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
в этом случае вопрос как отфетчить из курсора только требуемые поля без использования xml преобразования?
...
Рейтинг: 0 / 0
26.11.2019, 07:46
    #39894252
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
capuzi
в этом случае вопрос как отфетчить из курсора только требуемые поля без использования xml преобразования?
На колу мочало, начинай с начала. 22017669

http://www.bugtraq.ru/forum/faq/general/smart-questions.html] RTFM
...
Рейтинг: 0 / 0
26.11.2019, 09:34
    #39894271
capuzi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
по сообщению 22019912 о pipeline предполагал, что есть еще идеи, кроме использования xml или dbms_sql
всем спасибо
...
Рейтинг: 0 / 0
27.11.2019, 15:33
    #39895121
роман23t
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
По поводу вывода в pipeline функции произвольной выборки, нашел рабочий пример

https://stackoverflow.com/questions/14155844/return-resultset-from-function

Как я понял, мы для функции указываем тип anydataset для pipe - и использовать наш объектный тип, где мы переопределяем методы, которые использует SQL Engine, для определения этого типа "на лету". Далее с помощью dbms_sql парсим сам SQL запрос, а с помощью методов anydataset определяем его структуру и запихиваем данные в экземпляр нового типа.

Единственное, что он работает только если cursor_sharing = 'EXACT'.

Понять на пальцах и подогнать готовый пример под свои нужды наверное удалось. Что то вроде имплементации интерфейса выходит, но ощущения полного понимания у меня нет.
...
Рейтинг: 0 / 0
27.11.2019, 15:36
    #39895123
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
capuzi
по сообщению 22019912 о pipeline предполагал, что есть еще идеи, кроме использования xml или dbms_sql

Можно использовать pipelined, но унутре все одно придется разбирать и генерировать структуры, кроме того, появится проблема с организацией принудительного хард-парса запроса к pipelined при изменении структуры weak ref cursor.
...
Рейтинг: 0 / 0
27.11.2019, 16:11
    #39895137
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fetch нескольких полей из sys_refcursor
роман23t
в pipeline функции произвольной выборки
Зачем нужна произвольная выборка из pipeline? Для oci/jdbc клиента разницы реф-курсор или не реф нет. Внутри sql употреблятство все равно декларируется явно.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / fetch нескольких полей из sys_refcursor / 21 сообщений из 21, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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