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.