2

我的 Postgres 数据库将所有内容编码为 UTF-8,但在选择列时的查询中,我想知道它是否可以编码为拉丁文。我实际上不需要将其编码为拉丁语,但我需要知道是否可以将其编码为拉丁语。

拉丁语的意思是其他人通常用拉丁语表示的意思,即西欧人可以识别字符

IE

SELECT val 
FROM 
TABLE1
WHERE IS_LATIN(Val);

解决方案

我使用了下面发布的答案,首先我尝试了 python 函数,但它失败了,因为我没有安装该语言。然后我尝试了 pl/sql 函数,但由于缺少 RETURN 语句而失败,但我修复如下,现在可以正常工作

CREATE OR REPLACE FUNCTION is_latin(input text)
RETURNS boolean
LANGUAGE plpgsql
IMMUTABLE
AS $$
BEGIN
  PERFORM convert_to(input, 'iso-8859-15');
  RETURN true;
EXCEPTION
  WHEN untranslatable_character THEN
    RETURN false;
END;
$$;
4

1 回答 1

1

好吧,您需要更具体地了解“拉丁语”。

假设您的意思是 ISO-8859-15,典型的西欧

regress=> SELECT convert_to('a€bcáéíöâ', 'iso-8859-15');
      convert_to      
----------------------
 \x61a46263e1e9edf6e2
(1 row)

请注意,人们经常使用iso-8859-1,但它不支持€。

但是,您会遇到货币符号和其他通常出现在现代西欧文本中的问题。例如,₽ 不是 ISO-8859-15 的一部分。฿、₡、₹和其他主要货币也不是。(奇怪的是,¥ 在 ISO-8859-15 中)。

如果您想在没有错误的情况下进行测试,您需要使用 PL/Python 或类似工具,或者使用 PL/PgSQL 并捕获异常。

CREATE OR REPLACE FUNCTION is_latin(input text)
RETURNS boolean
LANGUAGE plpgsql
IMMUTABLE
AS $$
BEGIN
  PERFORM convert_to(input, 'iso-8859-15');
EXCEPTION
  WHEN untranslatable_character THEN
    RETURN false;
END;
$$;

regress=> SELECT is_latin('฿');
 is_latin 
----------
 f
(1 row)

但是,这会在每次调用时创建一个保存点,这可能会变得昂贵。所以也许 PL/Python 更好。这个假设server_encoding(假设它是 utf-8)是不明智的,所以它应该真正正确地检查。反正:

CREATE OR REPLACE FUNCTION is_latin(input text)
RETURNS boolean
LANGUAGE plpythonu
IMMUTABLE
AS $$
try:
    input.decode("utf-8").encode("iso-8859-1")
    return True
except UnicodeEncodeError:
    return False
$$;

另一种选择是创建一个正则表达式,其字符集与您想要允许的所有字符匹配,但我怀疑这会很慢而且很难看。不完整的例子:

SELECT 'ab฿cdé' ~ '^[a-zA-Z0-9.áéíóúÁÉÍÓÚàè]*$'

...您可能会使用 iso-8859-15 编码表来生成字符列表。

于 2014-08-13T13:39:06.147 回答