当我在下面的代码中尝试从unicode转换为utf8时 “函数convert_from(字符变化,未知)不存在”错误发生。
select convert_from(artists, 'UTF8') from songs where
to_tsvector('simple',convert_from(artists, 'UTF8'))
@@ plainto_tsquery('simple','alizee')
limit 100
列“艺术家”具有“TEXT”类型。
但是当我跑步时
select convert_from(E'\u0422\u0438\u043c\u0430\u0442\u0438', 'UTF8');
效果很好。
如何解决此问题? 我将不胜感激任何帮助。感谢
答案 0 :(得分:3)
来自documentation:convert_from(string bytea, src_encoding name)
。
所以将艺术家投射到bytea:
select convert_from(artists::bytea, 'UTF8') from songs where
to_tsvector('simple',convert_from(artists, 'UTF8'))
@@ plainto_tsquery('simple','alizee')
limit 100
答案 1 :(得分:2)
在我看来,您已经以7位ascii的形式获取了具有2字节unicode十六进制转义符(\uxxxx
)的数据,并将其存储在varchar
类型字段中。
convert_from
完全是处理该数据的错误方法。它不是utf-8,除了7位ASCII是utf-8的子集。如果你强制通过convert_from(..., 'utf-8')
,那么你就会得到你刚开始使用的blah\u0123
等等。
select convert_from(E'\u0422\u0438\u043c\u0430\u0442\u0438', 'UTF8');
出现的原因是convert_from
什么都不做。这是发生的事情:
PostgreSQL看到字面值E'\u0422\u0438\u043c\u0430\u0442\u0438'
并看到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
列这样的已知类型列值。这是类型安全的事情。
因此,要正确转换您的数据,您需要解码那些\u
转义符。 convert_from
不您想要的是什么,因为它是为将编码文本的二进制表示转换为本地数据库文本编码而设计的。
PostgreSQL支持字符串文字,因为我们通过查看它为E''
文字所做的事情来确定。我目前正在寻找一种向用户公开解码的功能。 decode(...)
不支持\u
转义,只支持八进制转义......