Выберите из всех таблиц внутри схемы, содержащей столбец с именем - PullRequest
0 голосов
/ 02 апреля 2019

Как я могу получить выбор (table_name, table_name.age)? Мне нужно получить значения из столбца "возраст" из всех таблиц, имеющих этот столбец /

У меня есть эта функция

CREATE OR REPLACE FUNCTION union_all_tables()
 RETURNS TABLE
  (
    age   bigint
  ) AS
$$
DECLARE
 dynamic_query text = '';
 r_row         record;
BEGIN
FOR r_row IN SELECT table_schema || '.' || table_name qualified_table_name
       FROM information_schema.COLUMNS
       WHERE column_name = 'age' 
LOOP
dynamic_query := dynamic_query || format('UNION SELECT ' ||                                      
                                       'age ' ||
                                       'FROM %s ',r_row.qualified_table_name) || E'\n'; -- adding new line for pretty print, it    is not necessary
END LOOP;

dynamic_query := SUBSTRING(dynamic_query, 7) || ';';

RAISE NOTICE 'Union all tables in staging, executing statement: %',    dynamic_query;
RETURN QUERY EXECUTE dynamic_query;
END;
$$
LANGUAGE plpgsql;

1 Ответ

1 голос
/ 02 апреля 2019

Вам не нужно генерировать ни одного огромного оператора UNION. Если вы используете RETURN QUERY, то результат этого запроса добавляется к общему результату функции каждый раз, когда вы ее используете.

При работе с динамическим SQL вы также должны использовать format() для правильной работы с идентификаторами.

Ваша функция может быть упрощена до:

CREATE OR REPLACE FUNCTION union_all_tables()
 RETURNS TABLE (table_schema text, table_name text, age bigint) 
AS
$$
DECLARE
 dynamic_query text = '';
 r_row         record;
BEGIN
  FOR r_row IN SELECT c.table_schema, c.table_name
               FROM information_schema.columns c
               WHERE c.column_name = 'age' 
  LOOP
    dynamic_query := format(
                      'select %L as table_schema, %L as table_name, age from %I.%I', 
                           r_row.table_schema, r_row.table_name, 
                           r_row.table_schema, r_row.table_name);
    RETURN QUERY EXECUTE dynamic_query;
  END LOOP;
END;
$$
LANGUAGE plpgsql;

Обратите внимание, что вся функция завершится ошибкой, если есть (хотя бы) одна таблица, в которой столбец age не является bigint.

...