Des améliorations sont possibles :
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
Points majeurs
-
PostgreSQL 8.4 a introduit le
USING
clause pourEXECUTE
, ce qui est utile pour plusieurs raisons. Récapitulatif dans le manuel :La chaîne de commande peut utiliser des valeurs de paramètre, qui sont référencées dans la commande sous la forme
$1, $2
, etc. Ces symboles font référence aux valeurs fournies dans le champUSING
clause. Cette méthode est souvent préférable à l'insertion de valeurs de données dans la chaîne de commande sous forme de texte :elle évite la surcharge d'exécution liée à la conversion des valeurs en texte et inversement, et elle est beaucoup moins sujette aux attaques par injection SQL puisqu'il n'est pas nécessaire de mettre des guillemets ou d'échapper.IOW, il est plus sûr et plus rapide que de créer une chaîne de requête avec une représentation textuelle des paramètres, même lorsqu'il est nettoyé avec
quote_literal()
.
Notez que$1, $2
dans la chaîne de requête, faites référence aux valeurs fournies dans leUSING
clause, pas aux paramètres de la fonction. -
Pendant que vous renvoyez
SELECT * FROM lookups.countries
, vous pouvez simplifier leRETURN
déclaration comme démontré :RETURNS SETOF lookups.countries
Dans PostgreSQL, un type composite est défini automatiquement pour chaque table. Utilise le. L'effet est que la fonction dépend du type et vous obtenez un message d'erreur si vous essayez de modifier la table. Supprimez et recréez la fonction dans un tel cas.
Cela peut être souhaitable ou non - c'est généralement le cas ! Vous voulez être informé des effets secondaires si vous modifiez les tables. De la façon dont vous l'avez, votre fonction s'interromprait silencieusement et déclencherait une exception lors de son prochain appel.
-
Si vous fournissez une valeur explicite par défaut pour le deuxième paramètre de la déclaration comme démontré, vous pouvez (mais vous n'êtes pas obligé) simplifier l'appel au cas où vous ne voudriez pas définir une limite supérieure avec
ends_with
.SELECT * FROM report_get_countries_new('Zaire');
au lieu de :
SELECT * FROM report_get_countries_new('Zaire', NULL);
Soyez conscient de la surcharge de fonctions dans ce contexte.
-
Ne citez pas le nom de la langue
même si c'est toléré (pour l'instant). C'est un identifiant.'plpgsql' -
Vous pouvez affecter une variable au moment de la déclaration. Enregistre une étape supplémentaire.
-
Les paramètres sont nommés dans l'en-tête. Supprimez les lignes absurdes :
starts_with ALIAS FOR $1; ends_with ALIAS FOR $2;