PostgreSQL CASE usage in functions

Yohan Hirimuthugoda picture Yohan Hirimuthugoda · Jan 19, 2012 · Viewed 23.1k times · Source

Can't we use CASE condition outside SQL SELECT statements?

E.g.:

CASE 
  WHEN old.applies_to = 'admin' THEN _applies_to = 'My Self'
  ELSE _applies_to = initcap(old.applies_to)
END
 _summary = _summary || '<li>Apply To: ' || _applies_to || '</li>';

I get the following error:

ERROR:  syntax error at or near "_summary"
LINE 86: _summary = _summary || '<li>Apply To: ' || _applies ...

Answer

Erwin Brandstetter picture Erwin Brandstetter · Jan 19, 2012

This concerns the conditional control structure CASE of the procedural language PL/pgSQL, to be used in plpgsql functions or DO statements.
Not to be confused with the CASE expression of SQL. Different language! And subtly different syntax rules, too.

While SQL CASE can be embedded in SQL expressions inside PL/pgSQL code (which is mostly just glue for SQL commands), you cannot have stand-alone SQL CASE expressions (would be nonsense).

-- inside plpgsql code block:
CASE 
   WHEN old.applies_to = 'admin' THEN
      _applies_to := 'My Self';
   ELSE
      _applies_to := initcap(old.applies_to);
END CASE;

You have to use fully qualified statements, terminated with semicolon (;) and END CASE to close it.

Answer to additional question in comment

According to documentation the ELSE keyword of a CASE statement is not optional. I quote from the link above:

If no match is found, the ELSE statements are executed; but if ELSE is not present, then a CASE_NOT_FOUND exception is raised.

However, you can use an empty ELSE:

CASE 
   WHEN old.applies_to = 'admin' THEN
      _applies_to := 'My Self';
   ELSE
      --  do nothing
END CASE;

This is different from SQL CASE expressions where ELSE is optional, but if the keyword is present, an expression has to be given, too!