Devi cambiare la lingua da sql a plpgsql se si desidera utilizzare le funzionalità procedurali di PL/pgSQL. Anche il corpo della funzione cambia.
Tieni presente che tutti i nomi dei parametri sono visibili nel corpo della funzione , inclusi tutti i livelli di istruzioni SQL. Se crei un conflitto di nomi, potresti dover qualificare come tabella i nomi delle colonne in questo modo:table.col , evitare la confusione. Poiché si fa riferimento ai parametri di funzione tramite riferimento posizionale ($n ) comunque, ho appena rimosso i nomi dei parametri per farlo funzionare.
Infine, THEN mancava nel IF dichiarazione - la causa immediata del messaggio di errore .
Si potrebbe usare COALESCE per sostituire NULL i valori. Ma funziona solo se c'è almeno una riga risultante. COALESCE non è possibile correggere "nessuna riga" può solo sostituire NULL effettivo valori.
Esistono diversi modi per coprire tutti i NULL casi. Nelle funzioni 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;
Oppure puoi racchiudere l'intera query in un COALESCE espressione in un SELECT esterno . "Nessuna riga" dal SELECT interno risulta in un NULL nell'espressione. Funziona come un semplice SQL oppure puoi racchiuderlo in una funzione 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;
Risposta correlata:
- Come visualizzare un valore predefinito quando non viene trovata alcuna corrispondenza in una query?
Riguardo ai conflitti di denominazione
Un problema era il conflitto di denominazione molto probabilmente. Sono state apportate importanti modifiche alla versione 9.0 . Cito le note sulla versione :
Le versioni successive hanno perfezionato il comportamento. In punti ovvi viene selezionata automaticamente l'alternativa giusta. Riduce il potenziale di conflitti, ma è ancora lì. Il consiglio si applica ancora in Postgres 9.3.