特殊字符场景下[DataField]<>''空字符串判断失效原因咨询
为什么
[DataField] <> ''对部分特殊字符的空判断失效? 这问题挺典型的,本质和SQL Server处理特殊Unicode字符的规则有关,我给你拆解清楚:
1. 那些特殊字符到底是什么?
你提到的N''、N''这类字符,属于超出当前数据库默认代码页映射范围的Unicode字符。SQL Server没法把它们转换成当前代码页(比如默认的SQL_Latin1_General_CP1_CI_AS)能识别的字符,所以显示时会用?(ASCII 63)代替——但注意,底层存储的还是原Unicode码位,ASCII()函数返回63只是因为它只能处理单字节字符,遇到无法映射的Unicode字符就返回这个默认值。
2. 为什么<> ''的判断会失效?
SQL Server的字符串相等比较,核心看的是排序规则定义的字符权重,不是字符本身的实际内容:
- 对于这些无法映射的Unicode字符,在大多数默认排序规则里,它们的排序权重被标记为“空等价”(权重为0)。
- 当你拿这类字符和空字符串
''比较时,SQL Server认为两者的权重相同,所以返回“相等”(也就是你看到的IIF(N'' = '', 1, 0)返回1)。 - 而
CHAR(63)是明确的单字节问号,它的排序权重是正常的非空值,所以CHAR(63) <> ''能正确返回1,这两者的本质是不一样的。
3. 为什么LEN([DataField]) > 0能正常工作?
LEN()函数的逻辑和字符串比较完全不同:它直接统计字符串里的实际字符数量(对于NVARCHAR来说,就是Unicode码位的数量),不管字符能不能被代码页映射,也不管排序权重。哪怕字符显示成?,只要它是一个有效的Unicode码位,LEN()就会把它算成1,所以LEN(N'')返回1,LEN(...) > 0自然能正确判断非空。
额外验证小技巧
你可以用UNICODE()函数查看这些字符的真实码位,比如:
SELECT UNICODE(N''); -- 返回该字符的实际Unicode码值,比如57487
另外,如果你想保留<> ''的写法,也可以用二进制排序规则绕过权重判断,直接对比字符的字节值:
SELECT IIF(N'' COLLATE Latin1_General_BIN2 <> N'', 1, 0); -- 会返回1,符合预期
内容的提问来源于stack exchange,提问作者gotqn
相关产品推荐
相关产品推荐

