28

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 ...
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
Yohan Hirimuthugoda
  • 1,053
  • 3
  • 11
  • 20

1 Answers1

41

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

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 a 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!

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
  • Thank you very much for your quick support Erwin. Very much appreciate it. – Yohan Hirimuthugoda Jan 19 '12 at 10:21
  • 1
    Another small question Erwin. Accroding to documentation ELSE condition of CASE statement is optional. But when I try to run series of WHEN conditions with statements without ELSE, Query browser giving me errors. `ERROR: case not found. HINT: CASE statement is missing ELSE part.` If you need I'll post relevant script part. – Yohan Hirimuthugoda Jan 19 '12 at 11:38
  • @Yohan: Please see additional answer. – Erwin Brandstetter Jan 19 '12 at 12:07
  • @Brandstetter: Thank you very much again. I went through documentation & saw that CASE_NOT_FOUND story. However I just found that we can omit ELSE if data I am looping through doesn't come to ELSE of CASE. Which mean CASE should have WHEN conditions to satisfy all data patterns which I am conditionally check. If my comment is not clear I'll post the script part which I used. – Yohan Hirimuthugoda Jan 19 '12 at 15:17
  • 2
    @Yohan: It would be unwise to skip the ELSE clause. Always include it. Raise an exception with an informative msg. in the ELSE clause if it should not occur. – Erwin Brandstetter Jan 19 '12 at 15:33
  • 1
    @Brandstetter: Thanks for the advice. I have change the logic as you suggest. – Yohan Hirimuthugoda Jan 20 '12 at 01:20
  • Is very confusing you place on the SQL CASE, a link to the PostgreSQL syntax definition which does not state anything about it being optional. – Evandro Coan Nov 28 '16 at 21:30
  • @addons_zz: It is essential to know that the procedural `CASE` of plpgsql is different from the SQL `CASE` construct. And I am clearly stating the *difference*. Seems you have been victim to the same confusion. Also, the manual for SQL `CASE` *clearly* states that `[ELSE result]` is optional. Square brackets (`[]`) denote optional syntax elements. – Erwin Brandstetter Nov 28 '16 at 22:13
  • Sorry, I have no Idea those square brackets `[]` means optional. – Evandro Coan Nov 28 '16 at 22:14