Oracle – создать временный набор результатов для использования в запросе

Как создать временный результирующий набор для использования в SQL без создания таблицы и вставки данных?

Пример: у меня есть список, например, 10 кодов. Я хочу поместить это в запрос и затем запросить базу данных, чтобы узнать, какие коды в этом временном списке не существуют в таблице.

Если он уже был в таблице, я мог бы сделать что-то вроде:

SELECT ITEM_CODE FROM TEMP_ITEMS MINUS SELECT ITEM_CODE FROM M_ITEMS 

Является ли их способ без использования PL / SQL и чистого SQL для создания временного набора строк перед запросом? Пожалуйста, не отвечайте с чем-то вроде:

 SELECT 1 FROM DUAL UNION ALL SELECT 2 FROM DUAL 

Я вроде как думаю о чем-то, где я могу предоставить свои коды в инструкции IN, и превращает это в строки для использования в более позднем запросе.

Изменить: так что все знают мою цель здесь, в основном я иногда получаю список кодов продуктов, которые мне нужны, чтобы найти, какие из них в списке не настроены в нашей системе. Я хочу, чтобы быстрый способ бросить это в SQL-запрос, чтобы я мог видеть, какие из них не находятся в системе (вместо импорта данных и т. Д.). Я обычно помещаю их в excel, затем делаю формулу, такую ​​как:

 ="'"&A1&"'," 

Чтобы я мог создать список, разделенный запятыми.

Если вы используете oracle 11g, вы можете сделать это

 with t as ( select (column_value).getnumberval() Codes from xmltable('1,2,3,4,5') ) SELECT * FROM t WHERE NOT EXISTS (SELECT 1 FROM M_ITEMS M WHERE codes = M.ITEM_CODE); 

или

 with t as ( select (column_value).getstringval() Codes from xmltable('"A","B","C"') ) SELECT * FROM t WHERE NOT EXISTS (SELECT 1 FROM M_ITEMS M WHERE codes = M.ITEM_CODE); 

Я бы пошел с:

 with t as ( select 1 as val from dual union all select 2 as val from dual ) select . . . 

И затем используйте «t» или как вы его называете, в последующем блоке запроса.

Я не уверен, что возражает против использования метода select. , , просто введите нужные значения в столбце Excel и создайте код для каждого значения, скопировав формулу. Затем вставьте результаты обратно в свой интерфейс запроса.

Если вы хотите использовать временную таблицу, вы можете использовать предложение values. В качестве альтернативы вы можете использовать строковые функции, если хотите только функциональность IN. Поместите значения в список, разделенный запятыми, и проверьте, соответствует ли оно определенному значению:

 where ','||<list>||',' like '%,'||col||',%' 

Есть два подхода, к которым я склонялся:

1. Глобальная временная таблица

Хотя вы говорите, что не хотите создавать таблицу, это зависит от того, почему вам не нужна таблица. Если вы решите создать глобальную временную таблицу, строки будут видны только для сеанса, который их вставил, так что это похоже на наличие личной таблицы в памяти, но дает вам все преимущества реальной таблицы, т. Е. Возможность запроса и присоединения к нему.

2. Конвейерная функция

Вы можете создать функцию, которая возвращает результаты в форме, которая может быть запрошена с помощью оператора TABLE() . Подробнее здесь: http://www.oracle-base.com/articles/misc/pipelined-table-functions.php

Это немного странно. Но вы можете анализировать строку в отдельные строки, используя регулярные выражения, предполагая, что вы используете 10g или более поздние версии. Например

 SQL> ed Wrote file afiedt.buf 1 SELECT REGEXP_SUBSTR('a,b,c,def,g', '[^ |,]+', 1, LEVEL) parsed_str 2 FROM dual 3* CONNECT BY LEVEL <= REGEXP_COUNT('a,b,c,def,g', '[^ |,]+') SQL> / PARSED_STR -------------------------------------------- a b c def g 

Лично я бы нашел конвейерную функцию таблицы или блок PL / SQL, который генерирует коллекцию, которую легче понять, но если вам нужно это сделать в SQL, вы можете.

Основываясь на вашем редактировании, если вы получаете список кодов продуктов, которые уже находятся в каком-то файле, кажется, имеет смысл использовать внешнюю таблицу для отображения файла в виде таблицы или для использования SQL * Loader для загрузки данные в таблицу (временную или постоянную), которую вы можете запросить. Если запретить любой из этих опций, если вы действительно хотите управлять списком в Excel вначале, было бы разумнее создать список IN в Excel и просто скопировать и пройти его в ваш запрос. Создание списка кодов, разделенных запятыми, в Excel только для синтаксического разбора этого списка в его составные элементы в SQL, похоже, слишком много шагов.

Это интересно, потому что это не объединение и не подходит для одного выбора. Вы должны ввести строку с разделителями ('a / b / c / def') два раза, хотя:

 SELECT regexp_substr('a/b/c/def', '[^/]+', 1, ROWNUM) var, regexp_substr('2/432/sd/fsd', '[^/]+', 1, ROWNUM) var2 FROM dual CONNECT BY LEVEL <= length(regexp_replace('a/b/c/def', '[^/]', '')) + 1; var var2 === ==== a 2 b 432 c sd def fsd 

Примечание. Кредиты идут по адресу : https://stackoverflow.com/a/1381495/463056

Таким образом, используя предложение with, он даст следующее:

 with tempo as ( SELECT regexp_substr('a/b/c/def', '[^/]+', 1, ROWNUM) var, regexp_substr('2/432/sd/fsd', '[^/]+', 1, ROWNUM) var2 FROM dual CONNECT BY LEVEL <= length(regexp_replace('a/b/c/def', '[^/]', '')) + 1 ) select ... 

или вы можете использовать его в разделе from:

 select ... from ( SELECT regexp_substr('a/b/c/def', '[^/]+', 1, ROWNUM) var, regexp_substr('2/432/sd/fsd', '[^/]+', 1, ROWNUM) var2 FROM dual CONNECT BY LEVEL <= length(regexp_replace('a/b/c/def', '[^/]', '')) + 1 ) tempo