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

plpgsql функция:Връща редове от изглед, създаден от произволна таблица

Може да работи така:

CREATE OR REPLACE FUNCTION tt_query(orig_name regclass, data_tt timestamp)
  RETURNS SETOF record AS
$func$
BEGIN

EXECUTE 'CREATE OR REPLACE TEMP VIEW tmp as 
select * 
from  '
|| orig_name 
|| ' where trigger_changed >'
|| quote_literal(data_tt)
|| ' ORDER BY trigger_changed DESC';

-- other work on view tmp

-- return the rows of view temp
RETURN QUERY
SELECT * FROM tmp;

END
$func$  LANGUAGE plpgsql;
  • Обърнете внимание на използването на тип идентификатор на обект regclass за автоматично избягване на SQL инжектиране.

  • Не използвайте остарелия синтаксис var ALIAS за $1 ако не ти се налага. Вместо това декларирайте имена на параметри.

  • Не бих използвал ключовата дума temp като идентификатор, дори ако това е разрешено. Използване на tmp вместо това.

  • Използвайте ВРЪЩАНЕ НА ЗАЯВКА за връщане на набор от записи. Това дори може да бъде статично повикване без EXECUTE . Вие обаче връщате анонимни записи и Postgres изисква списък с дефиниции на колони с всяко обаждане:

SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);

Това е доста тромаво.

По-добри решения

Ако знаете връщания тип (дори ако имената на таблиците се променят, списъкът с колони може да споделя едни и същи типове), декларирайте го по време на създаване. Обмислете този свързан въпрос:
PostgreSQL:ГРЕШКА:42601:изисква се списък с дефиниции на колони за функции, връщащи "запис"

Ако типът на връщане варира с предоставеното име на таблица все още има много по-добро решение. Тъй като създавате изглед с SELECT * FROM tbl , можете да използвате добре познатия тип на самата таблица като polymorphic параметър:

CREATE OR REPLACE FUNCTION tt_query(orig_name anyelement, data_tt timestamp)
  RETURNS SETOF anyelement AS
$func$
BEGIN

EXECUTE format('CREATE OR REPLACE TEMP VIEW tmp AS
   SELECT * FROM  %s
   WHERE  trigger_changed > %L
   ORDER  BY trigger_changed DESC'
  ,pg_typeof(orig_name)
  ,data_tt);

-- other work on view tmp

-- return the rows of view tmp
RETURN QUERY
SELECT * FROM tmp;

END
$func$  LANGUAGE plpgsql;

Опростено повикване:

SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');

Също така се използва format() за безопасно и просто конкатениране на низове.

Повече подробности в този свързан отговор:
Рефакторинг на PL/pgSQL функция, за да върне изхода на различни SELECT заявки




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да получите динамичен изглед за 12 работни дни в Postgresql?

  2. Постепенно архивиране на PostgreSQL и възстановяване в момента

  3. Erlang и PostgreSQL

  4. Рестартирайте Heroku Postgres Dev DB

  5. Как да задам кодиране в NpgsqlConnection