Udělal bych to takto:
CREATE OR REPLACE FUNCTION list(
_category varchar(100)
, _limit int
, _offset int
, _order_by varchar(100)
, _order_asc_desc text = 'ASC') -- last param with default value
RETURNS TABLE(id int, name varchar, clientname varchar, totalcount bigint)
LANGUAGE plpgsql AS
$func$
DECLARE
_empty text := '';
BEGIN
-- Assert valid _order_asc_desc
IF upper(_order_asc_desc) IN ('ASC', 'DESC', 'ASCENDING', 'DESCENDING') THEN
-- proceed
ELSE
RAISE EXCEPTION 'Unexpected value for parameter _order_asc_desc.
Allowed: ASC, DESC, ASCENDING, DESCENDING. Default: ASC';
END IF;
RETURN QUERY EXECUTE format(
'SELECT id, name, clientname, count(*) OVER() AS full_count
FROM design_list
WHERE ($1 = $2 OR category ILIKE $1)
ORDER BY %I %s
LIMIT %s
OFFSET %s'
, _order_by, _order_asc_desc, _limit, _offset)
USING _category, _empty;
END
$func$;
Základní funkce:použijte formát format()
bezpečně a elegantně zřetězit váš řetězec dotazu. Související:
- INSERT with název dynamické tabulky ve funkci spouštění
- Specifikátor formátu pro celočíselné proměnné ve format() pro EXECUTE?
ASC
/ DESC
(nebo ASCENDING
/ DESCENDING
) jsou pevná klíčová slova. Přidal jsem ruční kontrolu (IF ...
) a později zřetězit jednoduchým %s
. To je jedna způsob, jak uplatnit právní vstup. Pro usnadnění jsem přidal chybovou zprávu pro neočekávaný vstup a výchozí parametr, takže funkce je výchozí ASC
pokud je ve volání vynechán poslední parametr. Související:
- Volitelný argument v PL /pgSQL funkce
- CHYBA:vstupní parametry za parametrem s výchozí hodnotou musí mít výchozí hodnoty také v Postgres
Adresování Pavel's valid komentář
, zřetězím _limit
a _offset
přímo, takže dotaz je již naplánován s těmito parametry.
_limit
a _offset
jsou integer
parametry, takže můžeme použít obyčejný %s
bez nebezpečí SQL injection. Možná budete chtít potvrdit rozumné hodnoty (vyloučit záporné hodnoty a příliš vysoké hodnoty) před zřetězením ...
-
Použijte konzistentní konvenci pojmenování. Před všemi parametry a proměnné jsem uvedl podtržítko
_
, nejen některé . -
Nepoužívá se kvalifikace tabulky uvnitř
EXECUTE
, protože se jedná pouze o jednu tabulku aEXECUTE
má svůj samostatný rozsah. -
Některé parametry jsem pro upřesnění přejmenoval.
_order_by
místo_sort_by
;_order_asc_desc
místo_order
.