Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / SQL Macro и переменное число возвращаемых полей / 2 сообщений из 2, страница 1 из 1
23.12.2020, 19:29
    #40030621
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL Macro и переменное число возвращаемых полей
SQL Macro прекрасная обертка на ODCI table interface и с ними не надо тратить кучу времени на писанину ODCITableDescribe, ODCITablePrepare, ODCITableFetch... но как и ODCI table interface "страдает" от soft parse и посему при переменном числе возвращаемых полей параметры придется передавать "типа" литералом. Например:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
drop table samp-le purge
/
create table sample as
                select 1 category_id,1 categorization_id from dual union all
                select 2,1 from dual union all
                select 3,1 from dual union all
                select 4,2 from dual union all
                select 5,2 from dual union all
                select 6,3 from dual
/



Задача: вывести все комбинации category_id по одной из каждой categorization_id. Т.е. число полей результата зависит от числа categorization_id. Создаем SQL Macro:

Код: 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.
CREATE OR REPLACE
  FUNCTION COMBINATIONS(
                        P_CNT NUMBER
                       )
    RETURN VARCHAR2 SQL_MACRO
    IS
        V_SELECT_LIST  VARCHAR2(1000) := 'SELECT ';
        V_FROM_CLAUSE  VARCHAR2(1000) := ' FROM ';
        V_WHERE_CLAUSE VARCHAR2(1000) := ' WHERE 1 = 1';
        V_N            NUMBER := 1;
    BEGIN
        FOR V_REC IN (SELECT DISTINCT CATEGORIZATION_ID FROM SAMPLE ORDER BY CATEGORIZATION_ID) LOOP
          V_SELECT_LIST  := V_SELECT_LIST || 'S' || V_N || '.CATEGORY_ID CAT' || V_N || ',';
          V_FROM_CLAUSE  := V_FROM_CLAUSE || 'SAMPLE S' || V_N || ',';
          V_WHERE_CLAUSE := V_WHERE_CLAUSE || ' AND S' || V_N || '.CATEGORIZATION_ID = ' || V_REC.CATEGORIZATION_ID;
          EXIT WHEN V_N = P_CNT;
          V_N := V_N + 1;
        END LOOP;
        RETURN RTRIM(V_SELECT_LIST,',') || RTRIM(V_FROM_CLAUSE,',') || V_WHERE_CLAUSE;
END;
/

Function created.

SQL>



Выполняем:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT * FROM COMBINATIONS((SELECT COUNT(DISTINCT CATEGORIZATION_ID) FROM SAMPLE))
/

      CAT1       CAT2       CAT3
---------- ---------- ----------
         1          4          6
         1          5          6
         2          4          6
         2          5          6
         3          4          6
         3          5          6

6 rows selected.

SQL>



Добавляем новую categorization_id:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
INSERT
  INTO SAMPLE
  VALUES(7,4)
/
SELECT * FROM COMBINATIONS((SELECT COUNT(DISTINCT CATEGORIZATION_ID) FROM SAMPLE))
/

      CAT1       CAT2       CAT3
---------- ---------- ----------
         1          4          6
         1          5          6
         2          4          6
         2          5          6
         3          4          6
         3          5          6

6 rows selected.

SQL>



Как видим число полей осталось 3 а не 4. Изменим subquery - банально поставим второй пробел между DISTINCT и CATEGORIZATION_ID:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT * FROM COMBINATIONS((SELECT COUNT(DISTINCT  CATEGORIZATION_ID) FROM SAMPLE))
/

      CAT1       CAT2       CAT3       CAT4
---------- ---------- ---------- ----------
         1          4          6          7
         1          5          6          7
         2          4          6          7
         2          5          6          7
         3          4          6          7
         3          5          6          7

6 rows selected.

SQL>



Сделаем ROLLBACK и выполним SELECT с двумя пробелами:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SQL> ROLLBACK
  2  /

Rollback complete.

SQL> SELECT * FROM COMBINATIONS((SELECT COUNT(DISTINCT  CATEGORIZATION_ID) FROM SAMPLE))
  2  /

no rows selected

SQL>



Ну и возможно куча других "сюрпризов".

SY.
...
Рейтинг: 0 / 0
23.12.2020, 20:21
    #40030637
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL Macro и переменное число возвращаемых полей
SY,

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


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