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 :
- Comment afficher une valeur par défaut lorsqu'aucune correspondance n'est trouvée dans une requête ?
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.