select по динамическому списку одинаковых таблиц
Есть неопределённое количество схожих по DDL таблиц.
поля таблиц одинаковые: ID и VALUE
Таблицы имеют названия: от Z_VAL_001 до Z_VAL_ХХХ
нужен запрос, который выведет один общий результат по всем таблицам.
типа:
Select ID, VALUE FROM Z_VAL_001
union all
Select ID, VALUE FROM Z_VAL_002
union all
...
union all
Select ID, VALUE FROM Z_VAL_XXX
Список таблиц изменяется и содержится в другой таблице D_Z_TABLE c одним полем TABLE_NAME, в котором содержится перечень от Z_VAL_001 до Z_VAL_ХХХ
Ответы (2 шт):
Можно созбрать динамически такой запрос и позже использовать.
DECLARE
tSQL CLOB := '';
flag BOOLEAN := FALSE;
BEGIN
FOR cur IN (
SELECT TABLE_NAME FROM D_Z_TABLE
)
LOOP
IF (flag) THEN
tSQL := tSQL || ' union all ' || sys.utl_tcp.CRLF;
END IF;
tSQL := tSQL || ' select ID, VALUE from ' || cur.TABLE_NAME || sys.utl_tcp.CRLF;
IF (NOT flag) THEN
flag := TRUE;
END IF;
END LOOP;
-- Выводим сформированный запрос
dbms_output.put_line(tSQL);
END;
Так же можно создать процедуру и обращаться уже к процедуре, которая будет каждый раз собирать запрос и возвращать результат его выполнения:
PROCEDURE dinamicList(
res OUT SYS_REFCURSOR
)
IS
tSQL CLOB := '';
flag BOOLEAN := FALSE;
BEGIN
FOR cur IN (
SELECT TABLE_NAME FROM D_Z_TABLE
)
LOOP
IF (flag) THEN
tSQL := tSQL || ' union all ' || sys.utl_tcp.CRLF;
END IF;
tSQL := tSQL || ' select ID, VALUE from ' || cur.TABLE_NAME || sys.utl_tcp.CRLF;
IF (NOT flag) THEN
flag := TRUE;
END IF;
END LOOP;
-- Открываем курсор для чтения
OPEN res FOR tSQL;
END;
если правильно понял, от :a до :b ..
select -- агрегируем в строку
LISTAGG( t.tsql, chr(10)) WITHIN GROUP (ORDER BY t.n) AS tsql
from
(
select -- генерим построчно от :a до :b
x.n,
'Select ID, VALUE FROM Z_VAL_'|| LPAD(x.n, 3, '0')|| ' union all' as tsql
from ( select :a + level -1 as n from dual connect by level <= :b -:a ) x
union
select to_number(:b), 'Select ID, VALUE FROM Z_VAL_'|| LPAD(:b , 3, '0')
from dual
) t;
.. и далее "динамически" выполним этот tsql. Если (:b- :a) <100 - сработает :) и, если нужны уникальные, то union вместо union all