Řešení pro jednoduchý případ
Jak je vysvětleno v níže uvedených odpovědích, můžete použít registrované (řádkové) typy, a tak implicitně deklarovat návratový typ polymorfní funkce:
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;
Volejte:
SELECT * FROM public.get_table(NULL::public.users); -- note the syntax!
Vrátí úplnou tabulku (se všemi uživatelskými sloupci).
Počkejte! Jak?
Podrobné vysvětlení v této související odpovědi, kapitola"Různé kompletní typy tabulek" :
- Refaktorujte funkci PL/pgSQL tak, aby vrátila výstup různých SELECT dotazů
TABLE foo
je zkratka pro SELECT * FROM foo
:
- Existuje zkratka pro SELECT * FROM?
2 kroky pro zcela dynamický návratový typ
Ale to, o co se snažíte, je přísně nemožné v jednom SQL příkaz.
Chci předat
schema_name
atable_name
jako parametry pro funkci a získání seznamu záznamů podlecolumn_visible
pole vpublic.fields
tabulka.
Neexistuje žádný přímý způsob, jak vrátit libovolný výběr sloupců (typ návratu není v době volání znám) z funkce – nebo jakéhokoli SQL příkaz. SQL vyžaduje znát počet, názvy a typy výsledných sloupců v době volání. Více ve 2. kapitole této související odpovědi:
- Jak vygeneruji pivotované CROSS JOIN, kde výsledná definice tabulky není známa?
Existují různá řešení . Výsledek můžete zabalit do jednoho ze standardních typů dokumentů (json
, jsonb
, hstore
, xml
).
Nebo vygenerujete dotaz jedním voláním funkce a provedete výsledek dalším:
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;
Volejte:
SELECT public.generate_get_table('public', 'users');
Tím vytvoříte dotaz ve tvaru:
SELECT usr_id, usr FROM public.users;
Proveďte jej ve 2. kroku. (Možná budete chtít přidat čísla sloupců a sloupce pořadí.)
Nebo připojte \gexec
v psql pro okamžité provedení vrácené hodnoty. Viz:
Jak vynutit vyhodnocení poddotazu před připojením / posunutím dolů na cizí server
Nezapomeňte se bránit SQL injection:
- INSERT s názvem dynamické tabulky ve funkci spouštění
- Definovat názvy tabulek a sloupců jako argumenty ve funkci plpgsql?
varchar(100)
nedává příliš smysl pro identifikátory, které jsou ve standardním Postgresu omezeny na 63 znaků:
- Maximální počet znaků ve štítcích (názvy tabulek, sloupce atd.)
Pokud rozumíte tomu, jak identifikátor objektu zadejte regclass
funguje, můžete nahradit název schématu a tabulky singe regclass
sloupec.