Как выполнить SQL-запрос большого списка таблиц, используя переменные для имен таблиц? - PullRequest
0 голосов
/ 05 июля 2018

У меня есть вопрос о запуске запроса БД Oracle для нескольких таблиц. Есть ли способ сделать переменные имен таблиц итеративными, а не указывать каждое имя таблицы?

Пример фона

  1. Существует большое количество таблиц (например, TABLE_1 ... TABLE_100).
  2. Каждая из этих таблиц указана в столбце NAME другой таблицы (например, TABLE_LIST), где перечислено еще большее количество таблиц вместе с TYPE (например, "Account")
  3. В каждой из этих таблиц есть столбец VALUE, логический столбец ACTIVE.

Требования

  1. Запрос TABLE_LIST по TYPE = 'Account'
  2. Для каждой найденной таблицы запросите эту таблицу для всех записей, где столбец ACTIVE = 'N'
  3. Результаты показывают таблицу NAME и VALUE из каждой строки таблицы, где ACTIVE = 'N'.

Любые советы приветствуются.

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Существует низкотехнологичный и высокотехнологичный способ. Я поставлю их в отдельных ответах, чтобы люди могли голосовать за них. Это высокотехнологичная версия.

Настройка: То же, что и в низкотехнологичной версии.

CREATE TYPE my_row AS OBJECT (name VARCHAR2(128), value NUMBER)
/
CREATE TYPE my_tab AS TABLE OF my_row
/

CREATE OR REPLACE FUNCTION my_fun RETURN my_tab PIPELINED IS
  rec my_row := my_row(null, null);
  cur SYS_REFCURSOR;
BEGIN
  FOR t IN (SELECT name FROM table_list WHERE table_type='Account') LOOP
    rec.name  := dbms_assert.sql_object_name(t.name);
    OPEN cur FOR 'SELECT value FROM '||t.name||' WHERE active=''N''';
    LOOP
      FETCH cur INTO rec.value;
      EXIT WHEN cur%NOTFOUND;
      PIPE ROW(rec);      
    END LOOP;
    CLOSE cur;
  END LOOP;
END my_fun;
/

SELECT * FROM TABLE(my_fun);

NAME     VALUE
TABLE_1      1
TABLE_3      3
0 голосов
/ 06 июля 2018

Существует низкотехнологичный и высокотехнологичный способ. Я поставлю их в отдельных ответах, чтобы люди могли голосовать за них. Это низкотехнологичная версия.

Настройка:

CREATE TABLE table_1 (value NUMBER, active VARCHAR2(1) CHECK(active IN ('Y','N')));
CREATE TABLE table_2 (value NUMBER, active VARCHAR2(1) CHECK(active IN ('Y','N')));
CREATE TABLE table_3 (value NUMBER, active VARCHAR2(1) CHECK(active IN ('Y','N')));
INSERT INTO table_1 VALUES (1, 'N');
INSERT INTO table_1 VALUES (2, 'Y');
INSERT INTO table_3 VALUES (3, 'N');
INSERT INTO table_3 VALUES (4, 'Y');

CREATE TABLE table_list (name VARCHAR2(128 BYTE) NOT NULL, table_type VARCHAR2(10)); 
INSERT INTO  table_list (name, table_type) VALUES ('TABLE_1', 'Account');
INSERT INTO  table_list (name, table_type) VALUES ('TABLE_2', 'Something');
INSERT INTO  table_list (name, table_type) VALUES ('TABLE_3', 'Account');

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

SELECT 'SELECT '''||name||''' as name, value FROM '||name||
       ' WHERE active=''N'' UNION ALL' as sql  
  FROM table_list 
 WHERE table_type='Account';

SELECT 'TABLE_1' as name, value FROM TABLE_1 WHERE active='N' UNION ALL
SELECT 'TABLE_3' as name, value FROM TABLE_3 WHERE active='N' UNION ALL

Вам придется удалить последний UNION ALL и выполнить остальную часть запроса. Результат

NAME     VALUE
TABLE_1      1
TABLE_3      3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...