1

我有一个包含泰文和英文文本数据的列的表。NVARCHAR(255)。在 SSMS 中,我可以很容易地查询表并返回所有行。但是,如果我随后专门查询其中一个泰语结果,它不会返回任何行。

SELECT TOP 1000 [Province]
,[District]
,[SubDistrict]
,[Branch ]
FROM [THDocuworldRego].[dbo].[allDistricsBranches]

退货

Province    District    SubDistrict Branch 
อุตรดิตถ์   ลับแล   ศรีพนมมาศ   Northern
Bangkok  Khlong Toei    Khlong Tan  SSS1

但是这个查询:

SELECT [Province]
      ,[District]
      ,[SubDistrict]
      ,[Branch ]
  FROM [THDocuworldRego].[dbo].[allDistricsBranches]
  where [Province] LIKE 'อุตรดิตถ์'

不返回任何行。我需要做什么才能获得预期的结果。排序规则集是 Latin1_General_CI_AS。数据显示并插入没有错误只是无法搜索。

4

2 回答 2

1

两个问题:

  1. 传递到LIKE子句的字符串是VARCHAR由于没有以大写“N”为前缀。例如:

    SELECT 'อุตรดิตถ์' AS [VARCHAR], N'อุตรดิตถ์' AS [NVARCHAR]
    -- ?????????        อุตรดิตถ
    

    这里发生的是,当 SQL Server 解析查询批处理时,它需要确定所有文字/常量的确切类型和值。所以它计算出 that12是 anINT并且12.0是 aNUMERIC等等。它知道N'ดิ'isNVARCHAR是一个包罗万象的字符集,所以它按原样取值。但是,如前所述,'ดิ'isVARCHAR是 8 位编码,这意味着字符集由代码页控制。对于字符串文字和变量/参数,代码页用于VARCHARdata 是数据库的默认排序规则。如果字符串中有字符在数据库的默认排序规则使用的代码页上不可用,则它们要么被转换为“最合适”的映射,如果存在这样的映射,否则它们成为默认的替换字符:?.

    从技术上讲,由于数据库的默认排序规则控制字符串文字(和变量),并且由于“泰语”有一个代码页(在 Windows 排序规则中可用),因此可以有一个VARCHAR包含泰语字符的字符串(意思是:'ดิ',没有“N”前缀,可以工作)。但这需要更改数据库的默认排序规则,这比简单地在字符串文字前加上“N”要多得多。

    要深入了解此行为,请参阅我的两部分系列:

  2. 您需要在两端添加通配符:
    N'%อุตรดิตถ์%'

最终结果将如下所示:

WHERE [Province] LIKE N'%อุตรดิตถ์%'

编辑:
我刚刚编辑了问题以将“结果”格式化为更具可读性。现在看来,以下方法也可能有效(因为LIKE问题的谓词中没有使用通配符):

WHERE [Province] = N'อุตรดิตถ์'

编辑 2:如果没有以字符串文字为前缀的“N”,则为字符串
(即单引号内的内容) 。目标数据类型是什么(例如列)并不重要。这里的问题是数据的数据类型,而该源是字符串文字。与.NET 中的 a 不同,SQL Server 处理为 8 位编码 ( ; ASCII 值 0 - 127 在所有代码页中相同,扩展 ASCII 值 128 - 255 由代码页确定,并且可能是 2 字节序列用于 Double-字节字符集)和UTF-16 Little Endian(;Unicode 字符集,BMP 字符 0 - 65535 的 2 字节序列,65535 以上代码点的两个 2 字节序列)。使用 VARCHARNVARCHAR(255)string'string'VARCHARN'string'NVARCHAR'string'和传入一个VARCHAR变量是一样的。例如:

DECLARE @ASCII VARCHAR(20);
SET @ASCII = N'อุตรดิตถ์';
SELECT @ASCII AS [ImplicitlyConverted]
-- ?????????
于 2014-10-14T06:19:15.430 回答
0

可能是很多东西!

以十六进制打印出列的值和查询字符串的拳头。

SELECT     convert(varbinary(20)Province) as stored convert(varbinary(20),'อุตรดิตถ์') as query from allDistricsBranches;

这应该可以让您对问题有所了解。我认为最可能的原因是 ั、ิ、字符的输入顺序错误。它们显示为主要字母的一部分,但在内部存储为单独的字符。

于 2014-10-14T02:14:04.093 回答