函数convert_from(字符变化,未知)在Postgres中不存在



当我在下面的代码中试图从unicode转换为utf8时"function convert_from(character varying, unknown) does not exist"发生错误。

select convert_from(artists, 'UTF8') from songs where     
to_tsvector('simple',convert_from(artists, 'UTF8')) 
  @@ plainto_tsquery('simple','alizee') 
limit 100

专栏"艺术家"有"文本"类型。

但是当我奔跑的时候

select convert_from(E'u0422u0438u043cu0430u0442u0438', 'UTF8');

效果很好。

如何解决这个问题?我将感激任何帮助。由于

来自文档:convert_from(string bytea, src_encoding name)。所以演员们要注意:

select convert_from(artists::bytea, 'UTF8') from songs where     
to_tsvector('simple',convert_from(artists, 'UTF8')) 
  @@ plainto_tsquery('simple','alizee') 
limit 100

在我看来,你已经采取了7位ascii与2字节unicode十六进制转义(uxxxx)的形式的数据,并将其存储在varchar类型的字段。

convert_from是完全错误的方式来处理数据。它不是utf-8,只是7位ASCII是utf-8的子集。如果你强迫它通过convert_from(..., 'utf-8'),你就会得到你开始的东西,blahu0123等等。

select convert_from(E'u0422u0438u043cu0430u0442u0438', 'UTF8'); 看起来工作的原因是convert_from什么也不做。结果如下:

  • PostgreSQL看到字面值E'u0422u0438u043cu0430u0442u0438',并看到convert_from需要bytea的输入。

  • PostgreSQL解析字符串字面值的转义字符串格式,解码unicode转义以产生utf-8字符串Тимати。此时,就好像你写了:

    SELECT convert_from('Тимати', 'utf-8')
    
  • 因为convert_from需要bytea输入,PostgreSQL隐式地将数据强制转换为bytea,将文本字符串转换为utf-8编码的二进制,因为这是您的数据库服务器的文本编码。现在就好像你写了:

    SELECT convert_from( convert_to('Тимати','utf-8'), 'utf-8')
    

    ,当第一次转换完成后会变成:

    SELECT convert_from(BYTEA 'xd0a2d0b8d0bcd0b0d182d0b8', 'utf-8');
    

所以实际上你的convert_from是一种非常缓慢和低效的方式,什么都不做。

对于列值而不是文字,它不会这样工作,因为PostgreSQL会隐式地转换未知类型的文字,而不会隐式地转换已知类型的列值,如varchar column。这是类型安全的问题。

因此,要正确地转换数据,您需要解码这些u转义。convert_from而不是,因为它是为将编码文本的二进制表示转换为本地数据库文本编码而设计的。

PostgreSQL支持字符串字面值,正如我们看到它对E''字面值所做的那样。我目前正在寻找一个函数,暴露解码给用户,不过。decode(...)不支持u转义,只支持八进制转义…

最新更新