sql >> Databasteknik >  >> RDS >> PostgreSQL

plpgsql-funktion:Returnera rader från en vy skapad från en slumpmässig tabell

Det kan fungera så här:

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;
  • Observera användningen av objektidentifieringstypen regclass för att automatiskt undvika SQL-injektion.

  • Använd inte den föråldrade syntaxen var ALIAS för $1 om du inte måste. Deklarera parameternamn istället.

  • Jag skulle inte använda nyckelordet temp som identifierare, även om det är tillåtet. Använder tmp istället.

  • Använd RETURN QUERY för att returnera en uppsättning poster. Detta kan till och med vara ett statiskt samtal utan EXECUTE . Du returnerar dock anonyma poster och Postgres kräver en kolumndefinitionslista med varje samtal:

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

Det här är ganska otympligt.

Bättre lösningar

Om du vet returtypen (även om tabellnamnen ändras, kan listan med kolumner dela samma typer), deklarera den vid skapandet. Tänk på den här relaterade frågan:
PostgreSQL:FEL:42601:en kolumndefinitionslista krävs för funktioner som returnerar "record"

Om returtypen varierar med det angivna tabellnamnet finns det fortfarande en mycket bättre lösning. Eftersom du skapar en vy med SELECT * FROM tbl , kan du använda den välkända typen av själva tabellen som polymorf parameter:

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;

Förenklat samtal:

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

Använder även format() för säker och enkel strängsammansättning.

Mer information i detta relaterade svar:
Refaktorera en PL/pgSQL-funktion för att returnera utdata från olika SELECT-frågor




  1. MySQL BESTÄLLNING EFTER FÄLT med %

  2. OOP PHP PDO Mitt första projekt, gör jag rätt?

  3. Hur får man fråga om kolumnattribut från tabellnamn med PostgreSQL?

  4. Skillnaden mellan UNIX_TIMESTAMP och NOW() i MySQL