Je zde prostor pro vylepšení:
CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
, ends_with text = NULL)
RETURNS SETOF lookups.countries AS
$func$
DECLARE
sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
BEGIN
IF ends_with IS NOT NULL THEN
sql := sql || ' AND country_name <= $2';
END IF;
RETURN QUERY EXECUTE sql
USING starts_with, ends_with;
END
$func$ LANGUAGE plpgsql;
-- the rest is default settings
Hlavní body
-
PostgreSQL 8.4 zavedl
USING
klauzule proEXECUTE
, což je užitečné z několika důvodů. Shrnutí v návodu:Řetězec příkazu může používat hodnoty parametrů, na které se v příkazu odkazuje jako
$1, $2
, atd. Tyto symboly odkazují na hodnoty uvedené vUSING
doložka. Tato metoda je často vhodnější než vkládání datových hodnot do příkazového řetězce jako textu:vyhýbá se režii za běhu při převodu hodnot na text a zpět a je mnohem méně náchylná k útokům typu SQL-injection, protože není potřeba citovat nebo escapovat.IOW, je to bezpečnější a rychlejší než vytváření řetězce dotazu s textovou reprezentací parametrů, i když je dezinfikováno pomocí
quote_literal()
.
Všimněte si, že$1, $2
v řetězci dotazu odkazujte na dodané hodnoty vUSING
klauzule, ne na parametry funkce. -
Zatímco vrátíte
SELECT * FROM lookups.countries
, můžete zjednodušitRETURN
deklarace jako předvedena:RETURNS SETOF lookups.countries
V PostgreSQL je pro každou tabulku automaticky definován složený typ. Použij to. Výsledkem je, že funkce závisí na typu a při pokusu o změnu tabulky se zobrazí chybová zpráva. V takovém případě funkci zahoďte a znovu vytvořte.
To může nebo nemusí být žádoucí - obecně je to tak! Chcete-li být upozorněni na vedlejší účinky, pokud změníte tabulky. Jak to máte, vaše funkce by se tiše přerušila a vyvolala výjimku při příštím volání.
-
Pokud poskytnete explicitní výchozí nastavení pro druhý parametr v deklaraci, jak je ukázáno, můžete (ale nemusíte) zjednodušit volání v případě, že nechcete nastavit horní hranici pomocí
ends_with
.SELECT * FROM report_get_countries_new('Zaire');
místo:
SELECT * FROM report_get_countries_new('Zaire', NULL);
Uvědomte si v tomto kontextu přetížení funkcí.
-
Neuvádějte název jazyka
i když je to tolerováno (prozatím). Je to identifikátor.'plpgsql' -
Proměnnou můžete přiřadit v době deklarace. Ušetří krok navíc.
-
Parametry jsou pojmenovány v záhlaví. Zahoďte nesmyslné řádky:
starts_with ALIAS FOR $1; ends_with ALIAS FOR $2;