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 шт):

Автор решения: SwaD

Можно созбрать динамически такой запрос и позже использовать.

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

→ Ссылка