Funkce dezinfekce
To, co aktuálně máte, lze zjednodušit / dezinfikovat na:
CREATE OR REPLACE FUNCTION func_a (username text = '', databaseobject text = '')
RETURNS ????
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE
format ('SELECT * FROM %s v1 LEFT JOIN %I v2 USING (id)'
, CASE WHEN username = '*' THEN 'view1' ELSE 'view3' END
, databaseobject);
END
$func$;
Potřebujete pouze další instance BEGIN ... END
v těle funkce ke spuštění samostatných bloků kódu s vlastním rozsahem, což je zřídka potřeba.
Standardní operátor zřetězení SQL je ||
. +
je "kreativní" doplněk vašeho bývalého dodavatele.
Nepoužívejte identifikátory případu CaMeL, pokud je neuvedete dvakrát. Nejlépe je vůbec nepoužívejte Viz:
- Rozlišují se v názvech sloupců PostgreSQL velká a malá písmena?
varchar(4000)
je také přizpůsoben specifickým omezením SQL Server. V Postgresu nemá žádný konkrétní význam. Používejte pouze varchar(4000)
pokud skutečně potřebujete limit 4000 znaků. Použil bych pouze text
- kromě toho, že nepotřebujeme vůbec žádné proměnné zde, po zjednodušení funkce.
Pokud jste nepoužili format()
, přesto si přečtěte příručku zde.
Typ návratu
Nyní k vaší aktuální otázce:Návratový typ pro dynamický dotaz může být složitý, protože SQL vyžaduje, aby byl deklarován nejpozději v době volání. Pokud máte v databázi tabulku nebo pohled nebo složený typ, který již odpovídá seznamu definic sloupců, můžete použít toto:
CREATE FUNCTION foo()
RETURNS SETOF my_view AS
...
Jinak hláskujte seznam definic sloupců s (nejjednodušším) RETURNS TABLE
:
CREATE FUNCTION foo()
RETURNS TABLE (col1 int, col2 text, ...) AS
...
Pokud vytváříte typ řádku za pochodu, můžete vrátit anonymní záznamy:
CREATE FUNCTION foo()
RETURNS SETOF record AS
...
Ale pak musíte při každém volání poskytnout seznam definic sloupců, takže to téměř nikdy nepoužívám.
Nepoužil bych SELECT *
začít s. Pro návrat použijte definitivní seznam sloupců a odpovídajícím způsobem deklarujte svůj návratový typ:
CREATE OR REPLACE FUNCTION func_a(username text = '', databaseobject text = '')
RETURNS TABLE(col1 int, col2 text, col3 date)
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE
format ($f$SELECT v1.col1, v1.col2, v2.col3
FROM %s v1 LEFT JOIN %I v2 USING (id)$f$
, CASE WHEN username = '*' THEN 'view1' ELSE 'view3' END
, databaseobject);
END
$func$;
U zcela dynamických dotazů zvažte vytvoření dotazu ve vašem klientovi namísto použití funkce.
Nejprve musíte pochopit základy:
- Refaktorujte funkci PL/pgSQL tak, aby vrátila výstup různých SELECT dotazů
- PL/pgSQL v příručce Postgres
Pak existují pokročilejší možnosti s polymorfními typy, které umožňují předat návratový typ v době hovoru. Více v poslední kapitole:
- Refaktorujte funkci PL/pgSQL tak, aby vrátila výstup různých SELECT dotazů