这是脚本:
第一个脚本:
declare @a char(10) = 'AA%'
declare @b char(10) = 'AA001'
if @b LIKE @a
print 'Equals'
else
begin
print 'Not equals'
end
Run Code Online (Sandbox Code Playgroud)
它打印:
Not Equals
Run Code Online (Sandbox Code Playgroud)
我期待它打印Equals.但是下面的脚本@a在条件中没有使用:
第二个脚本:
declare @a char(10) = 'AA%'
declare @b char(10) = 'AA001'
if @b LIKE 'AA%'
print 'Equals'
else
begin
print 'Not equals'
end
Run Code Online (Sandbox Code Playgroud)
版画
Equals
Run Code Online (Sandbox Code Playgroud)
那么为什么第一个脚本认为它们不相等但第二个脚本认为它们相等?
答案实际上很简单,但这是一个很大的问题:这是因为char类型.
如果我们打印出2个变量:
print @a
print @b
Run Code Online (Sandbox Code Playgroud)
输出将是(点表示空白空间):
AA%.......
AA001.....
Run Code Online (Sandbox Code Playgroud)
所以第一个查询like对两个变量进行了处理,并且尾随空白使得它不相等,因为根据MSDN,从逻辑上讲,尾随空格(空格)是重要的:
如果查询中的比较是返回字符串LIKE'abc'(abc没有空格)的所有行,则返回以abc开头且具有零个或多个尾随空格的所有行.+使用包含char和varchar数据的模式的字符串比较可能无法通过LIKE比较,因为数据的存储方式.
第二个查询
第二个查询具有AA%隐式类型的文字,varchar因为AA001(类型char)将是AA%,它打印等于.为了重申文字的类型varchar,我使用了这个查询:
SELECT SQL_VARIANT_PROPERTY('AA%', 'BaseType')
Run Code Online (Sandbox Code Playgroud)
返回varchar.
更多信息
以下是来自MSDN的更多示例,以进一步明确:
以下示例将本地char变量传递给存储过程,然后使用模式匹配查找姓氏以指定字符集开头的所有员工.
-- Uses AdventureWorks
CREATE PROCEDURE FindEmployee @EmpLName char(20)
AS
SELECT @EmpLName = RTRIM(@EmpLName) + '%';
SELECT p.FirstName, p.LastName, a.City
FROM Person.Person p JOIN Person.Address a ON p.BusinessEntityID = a.AddressID
WHERE p.LastName LIKE @EmpLName;
GO
EXEC FindEmployee @EmpLName = 'Barb';
GO
Run Code Online (Sandbox Code Playgroud)
在该FindEmployee过程中,不返回任何行,因为@EmpLName只要名称包含少于20个字符,char变量()就包含尾随空格.因为LastName列是varchar,所以没有尾随空格.此过程失败,因为尾随空白很重要.但是,以下示例成功,因为尾随空格未添加到varchar变量.
- 使用AdventureWorks
CREATE PROCEDURE FindEmployee @EmpLName varchar(20)
AS
SELECT @EmpLName = RTRIM(@EmpLName) + '%';
SELECT p.FirstName, p.LastName, a.City
FROM Person.Person p JOIN Person.Address a ON p.BusinessEntityID = a.AddressID
WHERE p.LastName LIKE @EmpLName;
GO
EXEC FindEmployee @EmpLName = 'Barb';
Run Code Online (Sandbox Code Playgroud)
这是结果集:
FirstName LastName City
---------- -------------------- ---------------
Angela Barbariol Snohomish
David Barber Snohomish
(2 row(s) affected)
Run Code Online (Sandbox Code Playgroud)