无法返回查询泰语数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法返回查询泰语数据相关的知识,希望对你有一定的参考价值。
我有一个包含泰语和英语文本数据的列的表。 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。显示并插入数据,没有错误,无法搜索。
两个问题:
- 传递给
LIKE
子句的字符串是VARCHAR
,因为它没有以大写字母“N”作为前缀。例如:SELECT 'อุตรดิตถ์' AS [VARCHAR], N'อุตรดิตถ์' AS [NVARCHAR] -- ????????? อุตรดิตถ
这里发生的是当SQL Server解析查询批处理时,它需要确定所有文字/常量的确切类型和值。所以它发现12
是INT
和12.0
是NUMERIC
等。它知道N'ดิ'
是NVARCHAR
,这是一个包罗万象的字符集,所以它取值。但是,如前所述,'ดิ'
是VARCHAR
,它是一个8位编码,这意味着字符集由代码页控制。对于字符串文字和变量/参数,用于VARCHAR
数据的代码页是数据库的默认排序规则。如果字符串中的字符在数据库的默认排序规则使用的代码页上不可用,则它们将转换为“最佳拟合”映射,如果存在此类映射,则它们将成为默认替换字符:?
。 从技术上讲,由于数据库的默认排序规则控制字符串文字(和变量),并且由于存在“泰语”的代码页(在Windows排序规则中可用),因此可以使用包含泰语字符的VARCHAR
字符串(意思是:没有“N”前缀的'ดิ'
会工作)。但这需要更改数据库的默认排序规则,这比简单地在字符串文字前面加上“N”要多得多。 有关此行为的深入了解,请参阅我的两部分系列: Which Collation is Used to Convert NVARCHAR to VARCHAR in a WHERE Condition? (Part A of 2: “Duck”) Which Collation is Used to Convert NVARCHAR to VARCHAR in a WHERE Condition? (Part B of 2: “Rabbit”) - 您需要在两端添加通配符:
N'%อุตรดิตถ์%'
最终结果如下:
WHERE [Province] LIKE N'%อุตรดิตถ์%'
编辑:
我刚刚编辑了问题,将“结果”格式化为更具可读性。现在看来,以下内容也可能有效(因为问题中的LIKE
谓词中没有使用通配符):
WHERE [Province] = N'อุตรดิตถ์'
编辑2:
如果字符串文字没有前缀“N”,则字符串(即单引号内的字符串)为VARCHAR
。目标数据类型是什么并不重要(例如NVARCHAR(255)
列)。这里的问题是源数据的数据类型,该源是字符串文字。与.NET中的string
不同,SQL Server将'string'
处理为8位编码(VARCHAR
;所有代码页中的ASCII值0 - 127相同,代码页确定的扩展ASCII值128 - 255,以及可能的2字节序列对于双字节字符集)和N'string'
为UTF-16 Little Endian(NVARCHAR
; Unicode字符集,BMP字符0 - 65535的2字节序列,代码点高于65535的两个2字节序列)。使用'string'
与传入VARCHAR
变量相同。例如:
DECLARE @ASCII VARCHAR(20);
SET @ASCII = N'อุตรดิตถ์';
SELECT @ASCII AS [ImplicitlyConverted]
-- ?????????
可能是一些事情!
打印出列的值和十六进制查询字符串的拳头。
SELECT convert(varbinary(20)Province) as stored convert(varbinary(20),'อุตรดิตถ์') as query from allDistricsBranches;
这应该可以让您对问题有所了解。我认为最可能的原因是ั,ิ,字符输入的顺序错误。它们显示为主要字母的一部分,但在内部存储为单独的字符。
以上是关于无法返回查询泰语数据的主要内容,如果未能解决你的问题,请参考以下文章