Сделать в (SQL) динамическим для входящих значений - PullRequest
0 голосов
/ 19 июня 2019

Возможно ли в выражении быть динамическим? как динамическое разделение запятыми

например:

DATA=1
select * from dual
where
account_id in (*DATA);
DATA=2

select * from dual
where
account_id in (*DATA1,*DATA2);

ДЛЯ ДАННЫХ = n как сделать динамический / гибкий (запятую) оператор in для неизвестного количества.

select * from dual
where
account_id in (*DATAn,*DATAn+1,etc);

Ответы [ 3 ]

0 голосов
/ 19 июня 2019

Как я вижу, вы используете число в предложении Where, Substitution будет достаточно для решения вашей проблемы.

См. Пример ниже:

CREATE table t(col1 number);

insert into t values(1);
insert into t values(2);
insert into t values(3);

-- Substitution variable initialization
define data1=1;
define data2='1,2';

-

-- With data1
select * from t where col1 in (&data1);

Выход:

enter image description here

-- With data2
select * from t where col1 in (&data2);

Выход:

enter image description here

Надеюсь, это будет вам полезно.

Ура !!

0 голосов
/ 20 июня 2019

Основная проблема не в функции listagg, а в серьезном заблуждении, что только потому, что элементы в списке строк разделены запятыми, строка с запятыми в ней является списком.Не так.Рассмотрим таблицу со следующими строками.
Ключ
- Данные1
- Данные2
- Данные1, Данные2
И запрос: Выбрать * из таблицы_имя, где ключ = 'wanted_key';Теперь, если все запятые разделяют независимые элементы, то какое значение для "wanted_Key" необходимо для возврата только 3-й строки выше?Даже с предикатом IN 'Data1, Data2' по-прежнему всего 1 значение, а не 2. Для 2 значений это должно быть ('Data1', 'Data2').
Проблема, с которой вы сталкиваетесь в Listagg, не в запятой, а в том, что она не подходит.Listagg берет значения из нескольких строк и объединяет их в одну строку, разделенную запятыми, но не список, разделенный запятыми.Пример:

with elements as 
     ( select 'A' code, 'Data1' item  from dual union all 
       select 'A',      'Data2'       from dual union all 
       select 'A',      'Data3'       from dual  
     )
select listagg( item, ',') within group (order by item)
  from elements group by code;

(Возможно, вы также захотите попробовать 'Data1, Data2' как отдельный элемент. Осторожно.

Вам требуется запрос, который разбивает каждыйэлемент по отдельности. Это можно сделать с помощью

with element_list as  
     (select 'Data1,Data2,Data3' items from dual)  -- get paraemter string
   , parsed as 
     (select regexp_substr(items,'[^,]+',1,level) item
        from element_list connect by regexp_substr(items,'[^,]+',1,level) is not null -- parse string to elements
     )

CTE "parsed" теперь можно использовать как таблицу / представление в вашем запросе.
Это не будет работать так же, как запрос непосредственно с параметром,но снижение производительности - это стоимость динамических / гибких запросов.
Кроме того, при настройке это НЕ будет обрабатывать параметры, которые содержат запятые в отдельном элементе. Это потребовало бы гораздо больше кода, поскольку вы должны были бы определить / спроектировать, как сохранитьзапятая в этих элементах.

0 голосов
/ 19 июня 2019

Иерархический запрос может помочь.

  • acc CTE представляет образцы данных
  • строки # 9 - 11 - это то, что вы можете искать;данные объединяются со значением level псевдостолбца, возвращаемым иерархическим запросом

Вот так:

SQL> with acc (account_id) as
  2    (select 'data1' from dual union all
  3     select 'data2' from dual union all
  4     select 'data3' from dual union all
  5     select 'data4' from dual
  6    )
  7  select *
  8  from acc
  9  where account_id in (select 'data' || level
 10                       from dual
 11                       connect by level <= &n
 12                      );
Enter value for n: 1

ACCOU
-----
data1

SQL> /
Enter value for n: 3

ACCOU
-----
data1
data2
data3

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...