我正在尝试将一些文本(例如č
)存储在Postgres数据库中,但是在检索此值时,它会在屏幕上显示为?
。我不确定为什么这样做,我的印象是它是一个UTF-8不支持的角色,但是是UTF-8,但是,从第一个答案来看,这是一个不正确的假设
原始问题(可能仍然有效):
我已经读过关于UTF-8代理对,这可能会实现我的目标 要求,我已经看到一些涉及
stringinfo
的例子 对象TextElementEnumerators
,但我无法解决实际问题 概念证明。有人可以举例说明如何编写和阅读UTF-16 (可能使用这个代理对概念)到postgres数据库。 谢谢。
更新的问题:
为什么č
字符会从数据库中作为问号返回?
我们使用NPGSQL访问数据库和VB.Net。
答案 0 :(得分:5)
没有UTF-16中存在的字符,但UTF-8不存在。两者都能够编码所有Unicode。换句话说,如果你可以让UTF-8工作,它应该能够存储任何有效的Unicode文本。
编辑:Surrogate pairs实际上是UTF-16的一个功能,而不是UTF-8。它们允许不在基本多语言平面(BMP)中的字符表示为两个UTF-16代码单元。基本上,UTF-16通常被视为固定宽度编码(每个Unicode字符恰好两个字节),但这只允许BMP干净地编码。代理对是一种(相当hacky)扩展范围超出BMP的方法。
我非常怀疑你试图代表的角色是在BMP之外,所以我怀疑你需要到别处寻找问题。特别是,在进入数据库之前以及在获取文本之后,有必要转储文本的确切字符值(例如,将每个char
转换为int
)。理想情况下,在一个简短但完整的控制台应用程序中执行此操作。
答案 1 :(得分:1)
简短的回答,这不可能直接实现,因为PostgreSQL仅支持UTF-8字符集。
基于UTF-16的格式(例如Java,JavaScript,Windows)可以包含一半的代理对,这些代理对在UTF-8或UTF-32中没有表示形式。通过将Java,JavaScript,VB.Net字符串作为子字符串,可以轻松创建这些字符串。由于它们不能在UTF-8或UTF-32中表示,因此无法存储在仅支持PostgreSQL之类的UTF-8字符集的数据库中。
Windows路径名称可能包含一半的代理对,这些代理对不能读取为utf-8(https://github.com/rust-lang/rust/issues/12056)。
必须使用支持UTF-16 / CESU-8字符集的数据库系统,该字符集更适合Java / Android,JavaScript / NodeJS,.Net / wchar_t / Windows语言/平台。 (SQLServer,Oracle(UTF-8归类),DB2,Informix,HANA,SQL Anywhere,MaxDB通常支持这种字符集。
请注意,在基本多语言平面之外将表情符号表示为unicode代码点的情况下,这些差异也将与西方用户更加相关。
在postgres上,您可以: a)接受损失, b)将数据存储为二进制数据 要么 c)将它们翻译为 编码表示形式(例如JSON rfc将它们编码为两个转义字符,以便能够在基于UTF-8 / Ascii的网络格式中传输半个替代字符而不会丢失(https://tools.ietf.org/html/rfc4627第2.5节)。
例如图释位于基本的多语言平面之外,这个问题在西方世界也将变得更加重要。
取决于语言的选择Application Server(Java,Scala,C#/ Windows,JavaScript / NodeJS)与go以及对语言支持的投资水平(例如,在字素边界处使用ICU字符串拆分功能(https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries ),而不是简单的截断问题可能不那么重要,但是当今大多数企业系统和语言都属于UTF-16阵营,其软件使用简单的子字符串操作。
答案 2 :(得分:0)
关于存储/检索č
的问题检查运行Postgre db的字符集是否为UTF-8 字符集 (https://www.postgresql.org/docs/9.1/multibyte.html)或可以表示该字符的字符集。
检查是否已将与数据库的客户端连接设置为 执行适当的代码页转换(对于VB.Net,这将 从UTF-16LE到UTF-8或数据库字符集,通常是 连接字符串(字符集)上的参数)。
检查输入的内容是VB.net字节序列中的实际UTF-8 / UTF-16,而不是Windows-1250字节序列。
检查这不仅是对输出工具的限制,还是 控制台(例如Windows控制台通常不显示unicode字符,但使用Windows-12xx字符集(可以尝试https://superuser.com/questions/269818/change-default-code-page-of-windows-console-to-utf-8),但是通常最好在VB.Net调试器中检查字节序列。
检查CHAR / VARCHAR列的长度足以存储您的表示,即使在NFKD分解中表示也是如此。
您指出的字素具有几种不同的unicode表示形式。
U+010D LATIN SMALL LETTER C WITH CARON
U+0063 LATIN SMALL LETTER c followed by U+030C COMBINING CARON
和其他字符集的不同表示形式(例如,0xE8 ISO-8859-2 / Windows-1250(https://en.wikipedia.org/wiki/Windows-1250)或 ISO-8859-13 / Windows-1257。
所有unicode表示形式都属于基本的多语言平台,因此问题标题中指出并在下面回答的带有postgre的UTF-16替代问题可能与您的问题无关。