This simple function returns an ordered list of title
strings.
create or replace function testfunction1 ()
returns table (
id bigint,
lang_code tlang_code,
title varchar
)
stable language sql as $$
select
id, lang_code, title
from
testable
order by
title collate "es_ES";
$$;
select * from testfunction ();
id|lang_code|title |
--|---------|----------------|
12|DE |NOCH FESTZULEGEN|
16|DE |NOCH FESTZULEGEN|
8|DE |NOCH FESTZULEGEN|
14|ES |POR DETERMINAR |
6|ES |POR DETERMINAR |
10|ES |POR DETERMINAR |
5|EN |TO BE DETERMINED|
9|EN |TO BE DETERMINED|
13|EN |TO BE DETERMINED|
11|FR |À DÉTERMINER |
15|FR |À DÉTERMINER |
7|FR |À DÉTERMINER |
However, when I try to introduce a collation order with collate
I am not being able to get the syntax right to set the proper collation order based on the parameter _lang_code
.
create or replace function testfunction2 (_lang_code tlang_code)
returns table (
id bigint,
lang_code tlang_code,
title varchar
)
stable language sql as $$
select
id, lang_code, title
from
testable
where
lang_code = _lang_code
order by
title collate
case _lang_code
when 'EN' then "en_US"
when 'ES' then "es_ES"
when 'FR' then "fr_FR"
when 'DE' then "de_DE"
end asc;
$$;
The error is SQL Error [42601]: ERROR: syntax error at or near "case"
.
I have unsuccessfully tried positioning the case everywhere in the order by
clause. Maybe the "en_US" is not considered a scalar value?
EDIT
I've added where lang_code = _lang_code
after Laurenz Albe comment. This was a missing clause when traslating from my real problem to this simplified example.
However the issue with the case
remains with the same SQL error.
SOLUTION
As @Lorenz Albe pointed in a comment, "en_US"
is an identifier, not a scalar value. This prevents the case-when
structure from returning it in any of its when
branches. So no SQL way happens to exist.
As a work around, dynamic SQL from @doctore or moving the case to embrace the whole sentence, are both inelegant but functional solutions to the problem.