SQL Server手动输入与复制的查询条件值返回不同结果问题
问题原因
两段SQL的过滤条件看起来完全一致,本质是字符串中间的空白字符编码不同:
- 手动输入的
'A.J. Burnett'中间是普通半角空格,Unicode编码为U+0020(十进制32) - 从表中复制的
'A.J. Burnett'中间是非中断空格(Non-breaking Space),Unicode编码为U+00A0(十进制160)
由于name_full是nvarchar类型,支持存储所有Unicode字符,SQL的等值匹配会严格区分不同编码的字符,因此手动输入的普通空格字符串无法匹配到存储了非中断空格的记录。
你可以通过以下SQL验证两个字符串的字符编码差异:
-- 查看手动输入字符串每个字符的Unicode编码 SELECT SUBSTRING('A.J. Burnett', number, 1) AS char_val, UNICODE(SUBSTRING('A.J. Burnett', number, 1)) AS char_code FROM master..spt_values WHERE type = 'P' AND number BETWEEN 1 AND LEN('A.J. Burnett') -- 查看表中存储的目标值每个字符的Unicode编码 SELECT TOP 1 SUBSTRING(name_full, number, 1) AS char_val, UNICODE(SUBSTRING(name_full, number, 1)) AS char_code FROM bat_avg, master..spt_values WHERE type = 'P' AND number BETWEEN 1 AND LEN(name_full) AND name_full = 'A.J. Burnett'
修复方案
临时查询修复
- 直接使用Unicode前缀+正确字符:查询时给字符串加
N前缀声明为Unicode类型,直接使用从表中复制的带非中断空格的字符串即可:
SELECT Name_full FROM bat_avg WHERE name_full = N'A.J. Burnett'
- 统一替换空白字符后匹配:如果不想区分空格类型,可以在查询时将字段中的非中断空格替换为普通空格再匹配:
SELECT Name_full FROM bat_avg WHERE REPLACE(name_full, NCHAR(160), N' ') = 'A.J. Burnett'
如果存在全角空格、制表符等其他空白字符,可以扩展替换逻辑,SQL Server 2017及以上版本还可以用TRIM函数批量清除指定空白字符。
根源修复
直接清洗表中的name_full字段,把所有非标准空白字符替换为普通空格,避免后续查询出现同类问题:
UPDATE bat_avg SET name_full = REPLACE(name_full, NCHAR(160), N' ') WHERE name_full LIKE N'%' + NCHAR(160) + N'%'
内容的提问来源于stack exchange,提问作者Max Zhang
相关产品推荐
相关产品推荐

