此查询:
SELECT CASE WHEN 'abc ' = 'abc' THEN 1 ELSE 0 END
返回 1,即使“abc”显然不等于“abc”。同样,
SELECT CASE WHEN 'abc ' LIKE '%c' THEN 1 ELSE 0 END
也返回 1。然而,一个非常相似的查询:
SELECT * FROM #tempTable WHERE Name LIKE '%c'
没有返回 Name = 'abc ' 的行。
SQL Server 2008 R2, Windows 7 & 2008 R2, x64.
= 忽略尾随空格
len 忽略尾随空格
like 不会忽略尾随空格
SELECT CASE WHEN 'abc ' = 'abc' and DATALENGTH('abc ') = DATALENGTH('abc')
THEN 1 ELSE 0 END
您可以断言 DATALENGTH 不相关,但它仍然是解决方案。
原来 Name 列是
NVARCHAR
(即使它只包含 ASCII 字符)并且 NVARCHAR
的行为不同于 VARCHAR
:
SELECT CASE WHEN N'abc ' LIKE 'abc' THEN 1 ELSE 0 END
返回 0,同上用于列而不是文字。以下仍然返回 1:
SELECT CASE WHEN N'abc ' = 'abc' THEN 1 ELSE 0 END
所以
=
和LIKE
的工作方式不同,另一个特殊的区别。
附言。为了后代,这里有一些例子:
SELECT CASE WHEN 'abc ' = 'abc' THEN 1 ELSE 0 END
-- 1
SELECT CASE WHEN 'abc ' LIKE 'abc' THEN 1 ELSE 0 END
-- 1
SELECT CASE WHEN 'abc ' LIKE '%c' THEN 1 ELSE 0 END
-- 1
SELECT CASE WHEN N'abc ' = N'abc' THEN 1 ELSE 0 END
-- 1
SELECT CASE WHEN N'abc ' LIKE N'abc' THEN 1 ELSE 0 END
-- 0
SELECT CASE WHEN N'abc ' LIKE N'%c' THEN 1 ELSE 0 END
-- 0
CREATE TABLE #tempTable (Name VARCHAR(30));
INSERT #tempTable VALUES ('abc ');
SELECT * FROM #tempTable WHERE Name = 'abc';
-- returns row
SELECT * FROM #tempTable WHERE Name LIKE 'abc';
-- returns row
SELECT * FROM #tempTable WHERE Name LIKE '%c';
-- returns row
SELECT * FROM #tempTable WHERE Name LIKE N'%c';
-- does not return row
CREATE TABLE #tempTable2 (Name NVARCHAR(30));
INSERT #tempTable2 VALUES (N'abc ');
SELECT * FROM #tempTable2 WHERE Name = N'abc';
-- returns row
SELECT * FROM #tempTable2 WHERE Name LIKE N'abc';
-- does not return row
SELECT * FROM #tempTable2 WHERE Name LIKE '%c';
-- does not return row
SELECT * FROM #tempTable2 WHERE Name LIKE N'%c';
-- does not return row
如果您需要以这种方式比较事物但由于列的数据类型为 VARCHAR 而受到限制,则类似这样的内容基本上会用“X”填充尾随空格,这将导致比较失败:
DECLARE @1 VARCHAR(5), @2 VARCHAR(5)
SET @1 = 'ABC '
SET @2 = 'ABC'
IF REPLACE(@1,' ','X') = REPLACE(@2,' ','X')
PRINT 'Equal'
ELSE
PRINT 'Not Equal'
不是火箭科学,但如果您遇到需要处理的类似情况,至少可以解决 :)
TA,我不确定你是如何通过简单地提到 unicode(N) 来得到零的。我运行你的查询,它只给我 1 个。
您可以比较 LEN('abc ') 和 DATALENGTH('abc ') 并可以根据您的要求使用它们,或者您可以用一些字符替换尾随空格来解决您的问题。
我对 nvarchar 列也有类似的问题,想修复数据,所以我执行了以下操作来查找数据
select 'x' + username + 'x' from aspnet_users
where 'x' + username + 'x' <> 'x' + rtrim(username) + 'x'
where 子句将用户名与修剪后的版本进行比较
'x1234 x' <> 'x1234x'
为了修复数据,我刚刚做了一个更新
update aspnet_Users
set username = rtrim(username)
where 'x' + username + 'x' <> 'x' + rtrim(username) + 'x'