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