PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Définir une valeur de retour par défaut pour une fonction Postgres

Vous devez changer la langue de sql vers plpgsql si vous souhaitez utiliser les fonctionnalités procédurales de PL/pgSQL. Le corps de la fonction change également.

Sachez que tous les noms de paramètres sont visibles dans le corps de la fonction , y compris tous les niveaux d'instructions SQL. Si vous créez un conflit de nommage, vous devrez peut-être qualifier les noms de colonnes comme ceci :table.col , pour éviter toute confusion. Puisque vous vous référez aux paramètres de fonction par référence de position ($n ) de toute façon, j'ai juste supprimé les noms de paramètres pour que cela fonctionne.

Enfin, THEN manquait dans le IF déclaration - la cause immédiate du message d'erreur .

On pourrait utiliser COALESCE pour remplacer NULL valeurs. Mais cela ne fonctionne que s'il y a au moins une ligne résultante. COALESCE ne peut pas corriger "pas de ligne", il ne peut que remplacer le NULL réel valeurs.

Il existe plusieurs façons de couvrir tous les NULL cas. Dans les fonctions plpgsql :

CREATE OR REPLACE FUNCTION point_total(integer, date, OUT result bigint)
  RETURNS bigint AS
$func$
BEGIN

SELECT sum(p.points)          -- COALESCE would make sense ...
INTO   result
FROM   picks p
WHERE  p.user_id = $1
AND    p.gametime > $2
AND    p.points IS NOT NULL;  -- ... if NULL values were not ruled out

IF NOT FOUND THEN             -- If no row was found ...
   result := 0;               -- ... set to 0 explicitly
END IF;

END
$func$  LANGUAGE plpgsql;

Ou vous pouvez inclure toute la requête dans un COALESCE expression dans un SELECT externe . "Aucune ligne" du SELECT intérieur donne un NULL dans l'expression. Travaillez en SQL ordinaire, ou vous pouvez l'envelopper dans une fonction SQL :

CREATE OR REPLACE FUNCTION point_total(integer, date)
  RETURNS bigint AS
$func$
SELECT COALESCE(
  (SELECT sum(p.points)
   FROM   picks p
   WHERE  p.user_id = $1
   AND    p.gametime > $2
   -- AND    p.points IS NOT NULL  -- redundant here
  ), 0)
$func$  LANGUAGE sql;

Réponse connexe :

Concernant les conflits de noms

Un problème était le conflit de nommage le plus probable. Il y a eu des changements majeurs dans la version 9.0 . Je cite les notes de version :

Les versions ultérieures ont affiné le comportement. Dans les endroits évidents, la bonne alternative est choisie automatiquement. Réduit le potentiel de conflits, mais il est toujours là. Le conseil s'applique toujours dans Postgres 9.3.