这个简单的函数返回title
字符串的有序列表。
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 |
但是,当我尝试引入排序规则时,collate
我无法获得正确的语法来根据参数设置正确的排序顺序_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;
$$;
错误是SQL Error [42601]: ERROR: syntax error at or near "case"
。
我在order by
子句中的任何地方都没有尝试定位该案例。也许“ en_US”不被视为标量值?
where lang_code = _lang_code
在Laurenz Albe评论后添加的EDIT 。从我的实际问题过渡到此简化示例时,这是一个缺少的子句。
但是,问题case
仍然是相同的SQL错误。
正如@Lorenz Albe在评论中指出的那样,它"en_US"
是一个标识符,而不是标量值。这样可以防止case-when
结构在其任何when
分支中返回它。因此,没有SQL方法碰巧存在。
解决方法是,使用@doctore的动态SQL或将大小写移动到整个句子都是对问题的微妙但实用的解决方案。
考虑到您正在使用该参数_lang_code
来选择要过滤的“内部语言”。以下PL / SQL代码允许您collate
动态更改最终查询中的:
create or replace function testfunction2 (_lang_code varchar)
returns table (
id bigint,
lang_code varchar,
title varchar
)
language plpgsql
as $$
declare
final_collate varchar;
final_query varchar;
begin
if (_lang_code = 'EN') then
final_collate := 'en_US';
elsif (_lang_code = 'ES') then
final_collate := 'es_ES';
end if;
-- Include other use cases you need
final_query := 'select t.id, t.lang_code, t.title ' ||
'from test_table t ' ||
'where t.lang_code = ''' || _lang_code || ''' ' ||
'order by t.title collate "' || final_collate || '" asc';
--raise exception 'Final query: %', final_query;
return query
execute final_query;
end;$$
现在,您可以执行测试,甚至取消注释raise exception
以确保合适的“最终查询”:
select testfunction2('EN')
select testfunction2('ES')
PD:我已经改变的类型_lang_code
,并lang_code
给varchar
,因为我认为tlang_code
是一个自定义的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句