sql >> Databasteknik >  >> RDS >> PostgreSQL

Ställ in ett standardreturvärde för en Postgres-funktion

Du måste ändra språket från sql till plpgsql om du vill använda de processuella funktionerna i PL/pgSQL. Funktionskroppen ändras också.

Tänk på att alla parameternamn är synliga i funktionskroppen , inklusive alla nivåer av SQL-satser. Om du skapar en namnkonflikt kan du behöva tabellkvalificera kolumnnamn så här:table.col , för att undvika förvirring. Eftersom du refererar till funktionsparametrar med positionsreferens ($n ) hur som helst, jag tog precis bort parameternamn för att få det att fungera.

Slutligen, THEN saknades i IF uttalande - den omedelbara orsaken till felmeddelandet .

Man skulle kunna använda COALESCE för att ersätta NULL värden. Men det fungerar bara om det finns minst en resulterande rad. COALESCE kan inte fixa "ingen rad" det kan bara ersätta faktiska NULL värden.

Det finns flera sätt att täcka alla NULL fall. I plpgsql-funktioner :

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;

Eller så kan du bifoga hela frågan i en COALESCE uttryck i en yttre SELECT . "Ingen rad" från den inre SELECT resulterar i en NULL i uttrycket. Arbeta som vanlig SQL, eller så kan du slå in den i en sql-funktion :

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;

Relaterat svar:

Angående namnkonflikter

Ett problem var namnkonflikten mest troligt. Det har skett stora förändringar i version 9.0 . Jag citerar release notes :

Senare versioner har förfinat beteendet. På uppenbara ställen väljs det rätta alternativet automatiskt. Minskar risken för konflikter, men den finns kvar. Råden gäller fortfarande i Postgres 9.3.




  1. SQL INSERT för nybörjare

  2. inner join och where in() satsprestanda?

  3. Hur undkommer man strängar i SQL Server med PHP?

  4. Hur ska jag tolka Välj Distinct aliasRefForMe.field1 From [email protected] aliasRefForMe