sql >> Databáze >  >> RDS >> PostgreSQL

Funkce plpgsql:Vrací řádky z pohledu vytvořeného z náhodné tabulky

Mohlo by to fungovat takto:

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;
  • Všimněte si použití typu identifikátoru objektu regclass abyste se automaticky vyhnuli vkládání SQL.

  • Nepoužívejte zastaralou syntaxi var ALIAS for $1 pokud nemusíte. Místo toho deklarujte názvy parametrů.

  • Klíčové slovo temp bych nepoužil jako identifikátor, i když je to povoleno. Pomocí tmp místo toho.

  • Použijte RETURN QUERY vrátit sadu záznamů. Může se dokonce jednat o statické volání bez EXECUTE . Vracíte však anonymní záznamy a Postgres požaduje seznam definic sloupců při každém hovoru:

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

To je poněkud nepraktické.

Lepší řešení

Pokud víte návratový typ (i když se názvy tabulek mění, seznam sloupců může sdílet stejné typy), deklarujte jej při vytvoření. Zvažte tuto související otázku:
PostgreSQL:CHYBA:42601:pro funkce vracející "záznam" je vyžadován seznam definic sloupců

Pokud se typ návratu liší se zadaným názvem tabulky stále existuje mnohem lepší řešení. Protože vytváříte pohled pomocí SELECT * FROM tbl , můžete použít dobře známý typ samotné tabulky jako polymorfní parametr:

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;

Zjednodušené volání:

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

Také pomocí format() pro bezpečné a jednoduché zřetězení řetězců.

Další podrobnosti v této související odpovědi:
Refaktorování funkce PL/pgSQL tak, aby vrátila výstup různých SELECT dotazů




  1. Normalizace Unicode v Postgresu

  2. Proč by MySQL provedlo návrat None?

  3. Jak vynutit referenční integritu u dědičnosti jedné tabulky?

  4. Extrahujte MySQL pole řádku do PHP proměnných a pole