Postgres中的Oracle nls_sort等效项

时间:2020-05-12 14:33:09

标签: oracle postgresql collation nls-sort nls-comp

正在将数据库从Oracle迁移到Postgres。我正在尝试实现应用程序中的排序行为,在该行为中,需要在字母后面加上以数字开头的字母数字标签(在下面的示例中进行解释)。

我在Postgres中尝试了法语排序规则,但无法达到使用NLS_SORT "french"在Oracle中获得的相同结果。

发布Oracle查询后,我需要一个Postgres中的等效项,该等效项可以在DB中设置一次,以便应用程序以后使用。

Oracle:

ALTER SESSION SET NLS_SORT='FRENCH';
ALTER SESSION SET NLS_COMP=LINGUISTIC;
select LABEL from CARBON order by LABEL ;

 LABEL
    APPLE
    BALL
    102C
    108C
    108D

Postgres:

我尝试通过从frenchpg_collation创建名为fr-FR-x-icu的排序规则,并使用pgAdmin GUI更改现有表列,如下所示:

label character varying(255) COLLATE public.french NOT NULL

不走运,我得到同样的结果。

select LABEL from CARBON order by LABEL ;

LABEL
102C
108C
108D
APPLE
BALL

我也在Postgres中尝试了以下查询,它给出的结果与上面相同。我在Postgres中缺少什么吗?

select LABEL from CARBON order by LABEL collate "fr_FR"

1 个答案:

答案 0 :(得分:1)

您可以通过创建自定义ICU排序规则(可从PostgreSQL v10开始使用)轻松解决此问题,该排序规则对大于拉丁字符的数字进行排序:

CREATE COLLATION weird (
   LOCALE = 'fr-u-kr-latn-digit',
   PROVIDER = 'icu'
);

ALTER TABLE carbon ALTER label TYPE text COLLATE weird;

SELECT * FROM carbon ORDER BY label COLLATE weird;

 label 
-------
 APPLE
 BALL
 102C
 108C
 108D
(5 rows)

这是假设最新的ICU库,旧版本的语法略有不同。

对于旧版ICU库,您可能必须使用

CREATE COLLATION digitslast (
   PROVIDER = 'icu',
   LOCALE = 'fr@colReorder=latn-digit'
);