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
USINGeingefü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, $2referenziert werden usw. Diese Symbole beziehen sich auf Werte, die inUSINGangegeben 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, $2im Query-String beziehen sich auf die gelieferten Werte imUSINGKlausel, nicht zu den Funktionsparametern. -
Während Sie
SELECT * FROM lookups.countrieszurückgeben , können Sie denRETURNvereinfachen Deklaration wie demonstriert:RETURNS SETOF lookups.countriesIn 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_withkeine 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;