sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL - Zápis dynamického SQL do uložené procedury, která vrací sadu výsledků

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 pro EXECUTE , 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é v USING 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 v USING klauzule, ne na parametry funkce.

  • Zatímco vrátíte SELECT * FROM lookups.countries , můžete zjednodušit RETURN 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 'plpgsql' i když je to tolerováno (prozatím). Je to identifikátor.

  • 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;
    


  1. Průvodce návrhem databáze pro systém řízení zásob v MySQL

  2. Použijte tnsnames.ora v Oracle SQL Developer

  3. Použití Oracle JDeveloper 12c s Oracle Database 12c na platformě Oracle Cloud, část 3

  4. Zrušte pivot s názvem sloupce