PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

PostgreSQL — pisanie dynamicznego sql w procedurze składowanej, która zwraca zestaw wyników

Jest miejsce na ulepszenia:

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

Główne punkty

  • PostgreSQL 8.4 wprowadził USING klauzula EXECUTE , co jest przydatne z kilku powodów. Podsumuj w instrukcji:

    Ciąg polecenia może używać wartości parametrów, do których odwołuje się w poleceniu jako $1, $2 itp. Te symbole odnoszą się do wartości podanych w USING klauzula. Ta metoda jest często preferowana niż wstawianie wartości danych do ciągu poleceń jako tekstu:pozwala uniknąć narzutów w czasie wykonywania związanych z konwersją wartości na tekst iz powrotem i jest znacznie mniej podatna na ataki polegające na wstrzykiwaniu SQL, ponieważ nie ma potrzeby cytowania ani ucieczki.

    IOW, jest bezpieczniejsze i szybsze niż tworzenie ciągu zapytania z tekstową reprezentacją parametrów, nawet po oczyszczeniu za pomocą quote_literal() .
    Pamiętaj, że $1, $2 w ciągu zapytania odwołaj się do podanych wartości w USING klauzula, nie do parametrów funkcji.

  • Podczas zwracania SELECT * FROM lookups.countries , możesz uprościć RETURN deklaracja jak zademonstrowana:

    RETURNS SETOF lookups.countries
    

    W PostgreSQL istnieje typ kompozytowy definiowany automatycznie dla każdej tabeli. Użyj tego. Efekt jest taki, że funkcja zależy od typu i jeśli spróbujesz zmienić tabelę, pojawi się komunikat o błędzie. W takim przypadku upuść i odtwórz funkcję.

    To może być lub nie być pożądane - generalnie tak jest! Chcesz być świadomy skutków ubocznych zmiany tabel. Tak jak to zrobiłeś, twoja funkcja po cichu się zepsuje i zgłosi wyjątek przy następnym wywołaniu.

  • Jeśli podasz wyraźną wartość domyślną dla drugiego parametru w deklaracji, jak pokazano, możesz (ale nie musisz) uprościć wywołanie w przypadku, gdy nie chcesz ustawiać górnej granicy za pomocą ends_with .

    SELECT * FROM report_get_countries_new('Zaire');
    

    zamiast:

    SELECT * FROM report_get_countries_new('Zaire', NULL);
    

    Należy pamiętać o przeciążaniu funkcji w tym kontekście.

  • Nie cytuj nazwy języka 'plpgsql' nawet jeśli jest to tolerowane (na razie). To identyfikator.

  • Możesz przypisać zmienną w czasie deklaracji. Oszczędza dodatkowy krok.

  • Parametry są nazwane w nagłówku. Porzuć bezsensowne linie:

     starts_with ALIAS FOR $1;
     ends_with ALIAS FOR $2;
    


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Samodzielne dostarczanie kont użytkowników w PostgreSQL za pośrednictwem nieuprzywilejowanego dostępu anonimowego

  2. Mówienie użytkownikom, aby sami się rozwidlili

  3. Jak zmienić database_url w heroku?

  4. Jak zmapować pole tablicy PostgreSQL w Django ORM?

  5. django.db.utils.ProgrammingError:relacja już istnieje