powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Пару вопросов по табличной функции
5 сообщений из 30, страница 2 из 2
Пару вопросов по табличной функции
    #40105817
ArchiSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В прошлом сообщении накосячил с dbms_sql.

Вот правильный запрос для определения наименований полей:

Код: 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.
SQL> DECLARE
  2    L_AA_VAR TYPE_DEF_PKG.EMP_AAT;
  3    CUR_VAR_AA TYPE_DEF_PKG.EMP_RCT;
  4
  5    CUR PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
  6    COLS DBMS_SQL.DESC_TAB;
  7    NCOLS PLS_INTEGER;
  8
  9    CUR_EMP SYS_REFCURSOR;
 10  BEGIN
 11    OPEN CUR_VAR_AA FOR SELECT EMPNO, ENAME FROM EMP;
 12    L_AA_VAR := TYPE_DEF_PKG.TBL_FUNC_AA(CUR_VAR_AA);
 13
 14    OPEN CUR_EMP FOR SELECT * FROM TABLE(L_AA_VAR);
 15    CUR := DBMS_SQL.TO_CURSOR_NUMBER(RC => CUR_EMP);
 16
 17    DBMS_SQL.DESCRIBE_COLUMNS(CUR, NCOLS, COLS);
 18    FOR COLIND IN 1 .. NCOLS
 19      LOOP
 20        DBMS_OUTPUT.PUT_LINE(COLS(COLIND).COL_NAME);
 21      END LOOP;
 22    DBMS_SQL.CLOSE_CURSOR(CUR);
 23
 24  END;
 25  /
ATTR_1
ATTR_2

PL/SQL procedure successfully completed.



То есть это то, о чем писал выше andrey_anonymous, только и для 12.1 актуально.

andrey_anonymous
ArchiSQL
посмотрю Ваше решение

Определние типов для pipelined через курсор очень удобно, но в 18с и 19с oracle накосячил с генерацией типов - генерируются атрибуты с идентификаторами "ATTR_1", "ATTR_2", ... "ATTR_N" вместо определенных курсором.
Doc ID 2517404.1
Есть патч и два workarounds, но они описаны в ноте и потому я не могу тут об этом написать, не нарушая правил форума.
...
Рейтинг: 0 / 0
Пару вопросов по табличной функции
    #40105918
ArchiSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно резюмировать следующее:
  • 1. Коллекции типа nested table и varray могут быть объявлены на уровне схемы (поэтому могут быть как типами данных столбца таблицы, так и использоваться в SQL) и/или в спецификации пакета. В последнем случае при использовании в SQL запросах (коллекция как результирующее значение табличной функции (потоковой и/или pipelined) преобразованное оператором table в источник данных для запроса) происходит автоматическая генерация типов (записываются в словари данных) на уровне схемы.
Здесь кстати возник вопрос - в примере andrey_anonymous'а для pipelined table function указано, что эта функция возвращает тип nested table, объявленный в спецификации пакета. При этом генерирование данных этого типа не происходит (фетчится запись из курсора и подается на выход), Oracle все равно этот тип данных преобразует на уровень схемы?
    2. Обьявить тип index by коллекции на уровне схемы нельзя, поэтому для его использования в подпрограммах PL/SQL (в том числе, как результирующее значение табличной функции) этот тип должен быть объявлен в спецификация пакета.
3. Табличная функция может быть потоковой и конвеерной (pipelined). 3.1 В pipelined table function не допускается использование index by коллекции. 3.2 Для потоковой table function допускается использования index by коллекции. 3.2.1 Если такая коллекция индексирована по varchar2, то SQL ядро выдает ошибку на этапе sql запроса к табличной функции. 3.2.2 Индексирование должно идти по целочисленным значениям, при этом Oracle автоматически создает внутренний тип данных на уровне схемы для этой index by коллекции. Есть нюанс с идентификаторами атрибутов - назначаются "ATTR_1", "ATTR_2", ... вместо тех что определены в курсоре.
Код: 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.
55.
56.
57.
58.

SQL> CREATE OR REPLACE PACKAGE TYPE_DEF_PKG
  2  AS
  3    CURSOR EMP_CUR IS SELECT EMPNO, ENAME FROM EMP;
  4    TYPE EMP_RCT IS REF CURSOR RETURN EMP_CUR%ROWTYPE;
  5    TYPE EMP_AAT IS TABLE OF EMP_CUR%ROWTYPE;
  6    FUNCTION TBL_FUNC_AA (CV_IN IN EMP_RCT) RETURN EMP_AAT;
  7  END;
  8  /

Package created.

SQL> CREATE OR REPLACE PACKAGE BODY TYPE_DEF_PKG AS
  2    FUNCTION TBL_FUNC_AA (CV_IN IN EMP_RCT) RETURN EMP_AAT
  3     IS
  4       RETVAL EMP_AAT := EMP_AAT();
  5       REC CV_IN%ROWTYPE;
  6    BEGIN
  7       FETCH CV_IN BULK COLLECT INTO RETVAL;
  8       CLOSE CV_IN;
  9       RETURN RETVAL;
 10    END;
 11  END;
 12  /

Package body created.

SQL> DECLARE
  2    L_AA_VAR TYPE_DEF_PKG.EMP_AAT := TYPE_DEF_PKG.EMP_AAT();
  3    CUR_VAR_AA TYPE_DEF_PKG.EMP_RCT;
  4  BEGIN
  5    OPEN CUR_VAR_AA FOR SELECT EMPNO, ENAME FROM EMP;
  6    L_AA_VAR.EXTEND(14);
  7    L_AA_VAR := TYPE_DEF_PKG.TBL_FUNC_AA(CUR_VAR_AA);
  8
  9    FOR REC IN (SELECT * FROM TABLE(L_AA_VAR))
 10      LOOP
 11        NULL;
 12        DBMS_OUTPUT.PUT_LINE(REC.ATTR_1 || ' - ' || REC.ATTR_2);
 13      END LOOP;
 14  END;
 15  /
7839 - KING
7698 - BLAKE
7782 - CLARK
7566 - JONES
7788 - SCOTT
7902 - FORD
7369 - SMITH
7499 - ALLEN
7521 - WARD
7654 - MARTIN
7844 - TURNER
7876 - ADAMS
7900 - JAMES
7934 - MILLER

PL/SQL procedure successfully completed.
Покритикуйте, плиз, где что не так.
...
Рейтинг: 0 / 0
Пару вопросов по табличной функции
    #40105949
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArchiSQL,

как минимум, вот это
Код: plsql
1.
6    L_AA_VAR.EXTEND(14);


говорит о том, что вы плохо понимаете, что такое "присвоение значения переменной".

А вообще, игрушки подобного рода, обычно работают без явных багов (или "особенностей" реализации) в ограниченном числе ситуаций .
Не знаю, исправили ли в 20й версии все то, что наломали в 18й и 19й..
...
Рейтинг: 0 / 0
Пару вопросов по табличной функции
    #40105990
ArchiSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby
ArchiSQL,

как минимум, вот это
Код: plsql
1.
6    L_AA_VAR.EXTEND(14);


говорит о том, что вы плохо понимаете, что такое "присвоение значения переменной".


Ну началось, полетела душа в рай :) Очень ценное замечание )) Специально для Вас, можете 14 заменить на L_AA_VAR.COUNT. А так то я специально расширял коллекцию чтобы были пустые элементы и хотел кое-что попробовать, но я понимаю, это очень важный вопрос в контексте обсуждения табличных функций, не ускользнувший от Вашего орлиного взора, более того, потребовавший затрат Вашего времени на написание сообщения (тк ничего более полезного написано Вами не было :) )

booby

А вообще, игрушки подобного рода, обычно работают без явных багов (или "особенностей" реализации) в ограниченном числе ситуаций .
Не знаю, исправили ли в 20й версии все то, что наломали в 18й и 19й..


Одна вода, зачем писали, не понятно.... Но спасибо за Ваш пост, чувствуется та "пропасть" между Вашим сообщение и сообщением andrey_anonymous и Stax, где все четко, по делу.

Очень хотелось бы услышать комментарии последних, возможно я где-то был не прав, т.к. есть некоторые нестыковки с тем, что писал andrey_anonymous.
...
Рейтинг: 0 / 0
Пару вопросов по табличной функции
    #40105997
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArchiSQL
... Специально для Вас, можете 14 заменить на L_AA_VAR.COUNT.
....

я не могу.
И специально для нас не надо совершать бессмысленных действий.
...
Рейтинг: 0 / 0
5 сообщений из 30, страница 2 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Пару вопросов по табличной функции
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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