PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Функция за връщане на динамичен набор от колони за дадена таблица

Решение за простия случай

Както е обяснено в посочените отговори по-долу, можете да използвате регистрирани типове (редове) и по този начин имплицитно да декларирате връщания тип на полиморфна функция:

CREATE OR REPLACE FUNCTION public.get_table(_tbl_type anyelement)
  RETURNS SETOF anyelement AS
$func$
BEGIN
   RETURN QUERY EXECUTE format('TABLE %s', pg_typeof(_tbl_type));
END
$func$ LANGUAGE plpgsql;

Обадете се:

SELECT * FROM public.get_table(NULL::public.users);  -- note the syntax!

Връща пълната таблица (с всички потребителски колони).

Чакай! Как?

Подробно обяснение в този свързан отговор, глава„Различни типове пълни таблици“ :

  • Рефакторирайте функция PL/pgSQL, за да върнете резултатите от различни SELECT заявки

TABLE foo е просто съкращение от SELECT * FROM foo :

  • Има ли пряк път за SELECT * FROM?

2 стъпки за напълно динамичен тип връщане

Но това, което се опитвате да направите, е абсолютно невъзможно в единично SQL команда.

Искам да предам schema_name и table_name като параметри за функциониране и получаване на списък със записи, според column_visible поле вpublic.fields маса.

Няма директен начин за връщане на произволен избор на колони (тип на връщане, неизвестен по време на извикване) от функция - или който и да е SQL команда. SQL изисква да знае номера, имена и типове на получените колони по време на повикване. Повече във 2-ра глава на този свързан отговор:

  • Как да генерирам завъртано CROSS JOIN, където получената дефиниция на таблицата е неизвестна?

Има различнизаобиколни решения . Можете да увиете резултата в един от стандартните типове документи (json , jsonb , hstore , xml ).

Или генерирате заявката с едно извикване на функция и изпълнявате резултата със следното:

CREATE OR REPLACE FUNCTION public.generate_get_table(_schema_name text, _table_name text)
  RETURNS text AS
$func$
   SELECT format('SELECT %s FROM %I.%I'
               , string_agg(quote_ident(column_name), ', ')
               , schema_name
               , table_name)
   FROM   fields
   WHERE  column_visible
   AND    schema_name = _schema_name 
   AND    table_name  = _table_name
   GROUP  BY schema_name, table_name
   ORDER  BY schema_name, table_name;
$func$  LANGUAGE sql;

Обадете се:

SELECT public.generate_get_table('public', 'users');

Това създава заявка от формата:

SELECT usr_id, usr FROM public.users;

Изпълнете го във 2-ра стъпка. (Може да искате да добавите номера на колони и колони за поръчка.)
Или добавете \gexec в psql, за да изпълни незабавно върнатата стойност. Вижте:

Как да принудим оценка на подзаявката преди присъединяване/натискане надолу към чужд сървър

Защитете се срещу SQL инжектиране:

  • INSERT с динамично име на таблица в тригерна функция
  • Да дефинирате имената на таблици и колони като аргументи във функция plpgsql?
Настрани

varchar(100) няма много смисъл за идентификатори, които са ограничени до 63 знака в стандартния Postgres:

  • Максимален брой знаци в етикетите (имена на таблици, колони и т.н.)

Ако разбирате как идентификаторът на обекта тип regclass работи, можете да замените схемата и името на таблицата с един единствен regclass колона.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Проблеми при настройката на персонализиран първичен ключ при миграция на Rails 4

  2. PostgreSQL Висока наличност с архитектури Master-Slave и Master-Master

  3. Пресичане на множество масиви в PostgreSQL

  4. запазване на обект на python в таблица на postgres с туршия

  5. Функции с променлив брой входни параметри