为什么土耳其里拉是符号?替换为 ? 在 SQL Server 2008 数据库中

Ala*_*ord 3 t-sql sql-server unicode character-encoding sql-server-2008

当我将土耳其里拉符号插入到数据库的表中时,知道为什么土耳其里拉符号会被问号替换。见下图

在此处输入图片说明

Sol*_*zky 5

这不是字体问题。这是 Unicode (UTF-16) 与 8 位代码页字符集问题(即NVARCHARvs VARCHAR)。您尝试使用的字符在您执行此查询的数据库的默认排序规则所指示的特定代码页中不存在。DB 的默认排序规则使用的代码页在这里是相关的,因为您的字符串文字没有以大写“N”为前缀。如果是,则该字符串将被解释为 Unicode,并且不会发生任何转换。但由于您传入的是非 Unicode 字符串,因此在解析查询时,它将被强制放入当前数据库的默认排序规则代码页中。该代码页中没有的任何字符,并且没有最佳匹配映射,都会变成“?”。

您可以运行以下命令亲自查看:

SELECT '?';
PRINT '?';
Run Code Online (Sandbox Code Playgroud)

它既打印又显示在结果网格中 ?

如果要查看 SQL Server 认为它是什么字符,请运行以下命令:

SELECT ASCII('?');
Run Code Online (Sandbox Code Playgroud)

它会返回: 63

如果您想查看哪个字符的 ASCII 值为 63,请运行以下命令:

SELECT CHAR(63);
Run Code Online (Sandbox Code Playgroud)

它会返回: ?

现在运行这个:

SELECT N'?';
PRINT N'?';
Run Code Online (Sandbox Code Playgroud)

这将在结果网格中正确打印和显示。

要查看符号实际是什么字符值,请运行以下命令:

SELECT UNICODE(N'?'), UNICODE('?');
Run Code Online (Sandbox Code Playgroud)

这将返回:837863

但不是63问号吗?是的。那是因为没有在字符串文字前'?'加上大写VARCHAR字母“N”告诉 SQL Server 它是这样的,因此它会被转换为默认的未知字符。

现在,如果您要VARCHAR在具有与具有此字符的代码页相关联的排序规则的 DB 中执行此版本,那么即使没有使用大写“N”作为字符串文字的前缀,它也能工作。但是,目前,我找不到在 SQL Server 中使用的任何支持此字符的代码页。因此,它可能是一个仅限 Unicode 的字符,至少就 SQL Server 而言是这样。

解决这个问题的方法是:

  1. 将字段的数据类型更改为NVARCHAR(我在对该字段当前为 的问题的评论中看到VARCHAR)。如果该字段是VARCHAR那么即使您N在字符串上使用前缀,该字符仍将存储为?,除非列的排序规则指定的代码页支持此字符,但同样,我认为这可能是仅 Unicode 的特点。
  2. 将您的INSERT语句更改为以大写字母 "N": 为字符串字段的前缀(73, 4, N'(3) ?')。即使您将字段更改为NVARCHAR,如果您没有在字符串前加上前缀,NSQL Server 也会?先将字符转换为,然后插入?. 这是因为查询在执行之前会被解析,并且解析(对于非 Unicode 字符串文字和变量)是在数据库默认排序规则的代码页中完成的