.net 如何在Postgres数据库中存储UTF-16字符?

.net 如何在Postgres数据库中存储UTF-16字符?,.net,postgresql,encoding,utf-16,surrogate-pairs,.net,Postgresql,Encoding,Utf 16,Surrogate Pairs,我试图在Postgres数据库中存储一些文本(例如č),但是在检索此值时,它在屏幕上显示为?。我不知道它为什么会这样,我的印象是它是一个UTF-8中不支持的角色,但在UTF-8中,但是,从第一个答案来看,这是一个错误的假设 原始问题(可能仍然有效): 我读过关于UTF-8代理项对的文章,这可能会达到我想要的效果 require,我已经看到了一些涉及stringinfo 对象TextElementEnumerators,但我无法计算出一个实用的 概念证明 有人能举个例子说明你是如何写和读UTF-1

我试图在Postgres数据库中存储一些文本(例如
č
),但是在检索此值时,它在屏幕上显示为
。我不知道它为什么会这样,我的印象是它是一个UTF-8中不支持的角色,但在UTF-8中,但是,从第一个答案来看,这是一个错误的假设

原始问题(可能仍然有效):

我读过关于UTF-8代理项对的文章,这可能会达到我想要的效果 require,我已经看到了一些涉及
stringinfo
对象
TextElementEnumerators
,但我无法计算出一个实用的 概念证明

有人能举个例子说明你是如何写和读UTF-16的吗 (可能使用此代理项对概念)添加到postgres数据库。 多谢各位

更新问题: 为什么从数据库返回
č
字符作为问号


我们使用NPGSQL访问数据库和VB.Net。

UTF-16中没有字符,但UTF-8中没有字符。两者都能够对所有Unicode编码。换句话说,如果您可以让UTF-8工作,它应该能够存储任何有效的Unicode文本

编辑:实际上是UTF-16而不是UTF-8的一个特性。它们允许将不在基本多语言平面(BMP)中的字符表示为两个UTF-16代码单元。基本上,UTF-16通常被视为固定宽度编码(每个Unicode字符正好有两个字节),但这只允许对BMP进行干净的编码。代理项对是将范围扩展到BMP之外的一种(相当粗糙的)方法

我非常怀疑您试图表示的角色是否在BMP之外,因此我怀疑您需要在其他地方查找问题。特别值得一提的是,在文本进入数据库之前和获取之后,转储文本的精确字符值(例如,通过将每个
char
强制转换为
int
)。理想情况下,在一个简短但完整的控制台应用程序中执行此操作。

如何在Postgres数据库中存储所有UTF-16“字符”? 简而言之,这是不可能的,因为PostgreSQL只支持UTF-8字符集

基于UTF-16的格式,如Java、JavaScript和Windows,可以包含在UTF-8或UTF-32中没有表示形式的半代理项对。通过对Java、JavaScript、VB.Net字符串进行子串接,可以很容易地创建这些字符串。因为它们不能在UTF-8或UTF-32中表示,因此不能存储在只支持UTF-8字符集(如PostgreSQL)的数据库中

Windows路径名可能包含不能作为utf-8()读取的半个代理项对

我们必须使用支持UTF-16/CESU-8字符集的数据库系统,该字符集更适合于Java/Android、JavaScript/NodeJS、.Net/wchar\u t/Windows语言/平台。 (SQLServer、Oracle(UTF-8排序规则)、DB2、Informix、HANA、SQLAnywhere、MaxDB通常支持这样的字符集

注意,在基本的多语言平面之外,表情符号被表示为unicode代码点,这些差异对于西方用户也将变得更加相关

在博士后,您可以: a) 接受损失,, b) 将数据存储为二进制数据 或 c) 把它们翻译成 编码表示(例如,JSON rfc将其编码为两个转义字符,以便能够在基于UTF-8/Ascii的网络格式内传输半代理而不会丢失(第2.5节)

例如,表情符号位于基本的多语言平面之外,这一问题在西方世界也将变得更加相关


取决于语言应用服务器(Java、Scala、C#/Windows、JavaScript/NodeJS)与go的选择,以及对语言支持的投资水平(例如,在grapheme边界使用ICU字符串拆分函数()与简单的截断不同,这个问题可能不那么重要。但如今大多数企业系统和语言都属于UTF-16阵营,软件使用简单的子字符串操作。

关于存储/检索问题

  • 检查运行Postgre db的字符集是否为UTF-8 字符集 ()或可以表示该字符的字符集

  • 检查与数据库的客户端连接是否设置为 执行适当的代码页转换(对于VB.Net,这将 从UTF-16LE到UTF-8或数据库字符集,这通常是 连接字符串(字符集)上的参数

  • 检查输入是否为VB.net字节序列中的实际UTF-8/UTF-16,而不是Windows-1250字节序列

  • 检查这不仅仅是输出工具的限制或 控制台(例如,Windows控制台通常不显示unicode字符,但使用Windows-12xx字符集(可以尝试),但通常最好在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()或 ISO-8859-13/Windows-1257


    所有unicode表示法都属于基本的多语言平面,因此问题标题中指出并在下面回答的关于postgre的UTF-16代理问题可能与您的问题无关。

    我在这方面的知识并不丰富,所以听起来我错了-我将更新问题并删除我的假设。谢谢Jon,您的观点正确告诉我正确的方向,这可能是因为我们正在使用的Postgres版本或我们的群集软件。我编写了一个完全本地的测试,没有出现与生产系统中存在的问题相同的问题。@MrShoubs:这可能意味着问题不在您认为的地方-