У меня следующая проблема: в базе данных оракула я хотел бы запустить запрос, который перебирает какой-то словарь и берет из него значения, чтобы заполнить оператор where в запросе и вернуть набор записей для каждого отдельного запроса, что означает, 3 строки он должен вернуть три набора записей и затем объединить их. У меня есть следующие таблицы:

Dict (таблица)

country | filter_value
US      |      y
GE      |      N
UK      |      Y,N

Данные (таблица 1)

seller_id  |  country |     flag | type
   1       |  US      |      y   |   w
   2       |  US      |      n   |   w 
   3       |  GE      |      y   |   w
   4       |  GE      |      n   |   w
   5       |  UK      |      y   |   w
   6       |  UK      |      n   |   w 
   7       |  PT      |      y   |   w
   8       |  GR      |      n   |   w

Данные (таблица 2)

seller_id   |  country |     flag | type
   19       |  US      |      y   |   d
   28       |  US      |      n   |   d 
   33       |  GE      |      y   |   d
   44       |  GE      |      n   |   d
   54       |  UK      |      y   |   d
   66       |  UK      |      n   |   d 
   71       |  PT      |      y   |   d
   82       |  GR      |      n   |   d

И я хотел бы запустить что-то вроде этого:

union_data=empty table
for row in dict:
    select * from data(table1) where country=row.country and flag in (row.filter_value)
    select * from data(table2) where country=row.country and flag in (row.filter_value)
    union results from this both queries is one table meaning this union_data

Я совершенно новичок в PL / SQL и, честно говоря, не знаю, какие функции решат проблему.

0
data_b77 28 Июн 2020 в 09:45

1 ответ

Лучший ответ

Есть (как минимум) два варианта.

Первый из них проще и выглядит так: создайте функцию (возвращает рефкурсор), которая принимает country, находит значение фильтра и применяет оба "параметра" к оператору (операторам) select:

SQL> create or replace function f_test (par_country in varchar2)
  2    return sys_refcursor
  3  is
  4    l_filter_value dict.filter_value%type;
  5    l_rc           sys_refcursor;
  6  begin
  7    select filter_value
  8      into l_filter_value
  9      from dict
 10      where country = par_country;
 11
 12    open l_rc for
 13      select seller_id, country, flag, type
 14        from data
 15        where country = par_country
 16          and flag = l_filter_value
 17      union all
 18      select seller_id, country, flag, type
 19        from data2
 20        where country = par_country
 21          and flag = l_filter_value;
 22
 23    return l_rc;
 24  end;
 25  /

Function created.

Тестирование:

SQL> select f_test('US') from dual;

F_TEST('US')
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

 SELLER_ID COUNTRY    FLAG TYPE
---------- ---------- ---- ----
         1 US         Y    W
        19 US         Y    D


SQL>

Если это слишком просто (что означает: вы не можете / не хотите этого делать), используйте динамический SQL. Принцип аналогичен предыдущему. Этот пример включает "что, если DICT таблица содержит оба Y,N в filter_value" - в этом случае разделение извлекает filter_value по строкам (это то, что делают иерархические подзапросы).

SQL> create or replace function f_test (par_country in varchar2)
  2    return sys_refcursor
  3  is
  4    l_filter_value dict.filter_value%type;
  5    l_rc           sys_refcursor;
  6  begin
  7    select filter_value
  8      into l_filter_value
  9      from dict
 10      where country = par_country;
 11
 12    open l_rc for
 13      select seller_id, country, flag, type
 14        from data
 15        where country = par_country
 16          and flag in (select regexp_substr(l_filter_value, '[^,]+', 1, level)
 17                       from dual
 18                       connect by level <= regexp_count(l_filter_value, ',') + 1
 19                      )
 20      union all
 21      select seller_id, country, flag, type
 22        from data2
 23        where country = par_country
 24          and flag in (select regexp_substr(l_filter_value, '[^,]+', 1, level)
 25                       from dual
 26                       connect by level <= regexp_count(l_filter_value, ',') + 1
 27                      );
 28
 29    return l_rc;
 30  end;
 31  /

Function created.

Тестирование:

SQL> select f_test('US') from dual;

F_TEST('US')
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

 SELLER_ID COUNTRY    FLAG TYPE
---------- ---------- ---- ----
         1 US         Y    W
        19 US         Y    D


SQL> select f_test('UK') from dual;

F_TEST('UK')
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

 SELLER_ID COUNTRY    FLAG TYPE
---------- ---------- ---- ----
         5 UK         Y    W
         6 UK         N    W
        54 UK         Y    D
        66 UK         N    D


SQL>
1
Littlefoot 28 Июн 2020 в 19:19