Es gibt Raum für Verbesserungen:
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
Wichtige Punkte
-
PostgreSQL 8.4 hat den
USING
eingeführt Klausel fürEXECUTE
, was aus mehreren Gründen nützlich ist. Zusammenfassung im Handbuch:Die Befehlszeichenfolge kann Parameterwerte verwenden, die im Befehl als
$1, $2
referenziert werden usw. Diese Symbole beziehen sich auf Werte, die inUSING
angegeben werden Klausel. Diese Methode ist oft dem Einfügen von Datenwerten in die Befehlszeichenfolge als Text vorzuziehen:Sie vermeidet Laufzeit-Overhead durch das Konvertieren der Werte in Text und zurück und ist viel weniger anfällig für SQL-Injection-Angriffe, da keine Anführungszeichen oder Escapezeichen erforderlich sind /P>IOW, es ist sicherer und schneller als das Erstellen einer Abfragezeichenfolge mit Textdarstellung von Parametern, selbst wenn es mit
quote_literal()
bereinigt wird .
Beachten Sie, dass$1, $2
im Query-String beziehen sich auf die gelieferten Werte imUSING
Klausel, nicht zu den Funktionsparametern. -
Während Sie
SELECT * FROM lookups.countries
zurückgeben , können Sie denRETURN
vereinfachen Deklaration wie demonstriert:RETURNS SETOF lookups.countries
In PostgreSQL wird für jede Tabelle automatisch ein zusammengesetzter Typ definiert. Benutze es. Der Effekt ist, dass die Funktion vom Typ abhängt und Sie eine Fehlermeldung erhalten, wenn Sie versuchen, die Tabelle zu ändern. In einem solchen Fall die Funktion löschen und neu erstellen.
Dies kann wünschenswert sein oder nicht – im Allgemeinen ist es das! Sie möchten auf Nebenwirkungen aufmerksam gemacht werden, wenn Sie Tabellen ändern. So wie Sie es haben, würde Ihre Funktion stillschweigend abbrechen und beim nächsten Aufruf eine Ausnahme auslösen.
-
Wenn Sie eine explizite Standardeinstellung angeben für den zweiten Parameter in der Deklaration kann man (muss aber nicht) den Aufruf vereinfachen, falls man mit
ends_with
keine Obergrenze setzen will .SELECT * FROM report_get_countries_new('Zaire');
statt:
SELECT * FROM report_get_countries_new('Zaire', NULL);
Beachten Sie in diesem Zusammenhang das Überladen von Funktionen.
-
Geben Sie den Sprachnamen
auch wenn das (vorerst) geduldet wird. Es ist eine Kennung.'plpgsql' -
Sie können eine Variable zum Zeitpunkt der Deklaration zuweisen. Spart einen zusätzlichen Schritt.
-
Parameter werden in der Kopfzeile benannt. Lassen Sie die unsinnigen Zeilen weg:
starts_with ALIAS FOR $1; ends_with ALIAS FOR $2;