SQL中的值为USERNAME = ADMIN PASSWORD = ADMIN
SELECT * FROM TBL_USER
WHERE USERNAME='ADMIN'
AND PASSWORD COLLATE LATIN1_GENERAL_CS_AS=N'ADMIN'
以上查询工作正常。
2)如果我在密码前添加一个空格。
SELECT * FROM TBL_USER
WHERE USERNAME='ADMIN'
AND PASSWORD COLLATE LATIN1_GENERAL_CS_AS=N' ADMIN'
这也是正确的,因为它返回一条说错密码的消息。
3)如果我在密码末尾添加一个空格:
SELECT * FROM TBL_USER
WHERE USERNAME='ADMIN'
AND PASSWORD COLLATE LATIN1_GENERAL_CS_AS=N'ADMIN '
此查询应该失败,但它不会检索数据。
任何人都可以帮助我。第三个条件应该失败,因为表中的值是'admin',提供的值是'admin'(结尾有空格)。
答案 0 :(得分:3)
而不是使用 = 运算符使用 LIKE (不使用%通配符)
SELECT * FROM TBL_USER WHERE USERNAME='ADMIN'
AND PASSWORD COLLATE LATIN1_GENERAL_CS_AS LIKE N'ADMIN '
这就是为什么:SQL WHERE clause matching values with trailing spaces
答案 1 :(得分:2)
这是预期的behaviour of trailing spaces
SQL Server遵循ANSI / ISO SQL-92规范(第8.2节, ,关于如何比较字符串的一般规则#3) 有空格。 ANSI标准要求填充字符 比较中使用的字符串,以便它们的长度匹配 比较它们。填充直接影响WHERE的语义 和HAVING子句谓词和其他Transact-SQL字符串 比较。例如,Transact-SQL考虑字符串' abc'和 ' abc'等同于大多数比较操作。
此规则的唯一例外是LIKE谓词。当正确的时候 LIKE谓词表达式的一侧具有带尾随的值 空间,SQL Server不会将这两个值填充到相同的长度 在比较之前。因为喜欢的目的 根据定义,谓词是为了促进模式搜索 比简单的字符串相等测试,这不违反该部分 前面提到的ANSI SQL-92规范。
我建议你在where
条款中添加另一个条件:
And DATALENGTH(Password) = DATALENGTH(N'ADMIN ')
这将添加另一个检查以确保输入值长度与数据库值相同。
完整示例:
Declare @tblUser table
(
Username nvarchar(50),
Password nvarchar(50)
)
Insert into @tblUser
Values (N'ADMIN',N'ADMIN')
select *
From @tblUser
Where Username = N'ADMIN'
And Password Collate LATIN1_GENERAL_CS_AS = N'ADMIN'
select *
From @tblUser
Where Username = N'ADMIN'
And Password Collate LATIN1_GENERAL_CS_AS = N' ADMIN'
select *
From @tblUser
Where Username = N'ADMIN'
And Password Collate LATIN1_GENERAL_CS_AS = N'ADMIN '
And DATALENGTH(Password) = DATALENGTH(N'ADMIN ')
答案 2 :(得分:0)
你可以在支票上做一个正确的修剪。
SELECT * FROM TBL_USER
WHERE USERNAME='ADMIN' AND PASSWORD COLLATE LATIN1_GENERAL_CS_AS=RTRIM(N'ADMIN ')