由于数据存储方式的原因,使用包含 char 和 varchar 数据的模式的字符串比较可能无法通过 LIKE 比较。您应当了解每种数据类型的存储方式以及导致 LIKE 比较失败的原因。以下示例将本地 char 变量传递给存储过程,然后使用模式匹配来查找其姓氏以一组指定的字符开始的所有雇员。
复制代码
USE AdventureWorks;
GO
CREATE PROCEDURE FindEmployee @EmpLName char(20)
AS
SELECT @EmpLName = RTRIM(@EmpLName) + '%';
SELECT c.FirstName, c.LastName, a.City
FROM Person.Contact c JOIN Person.Address a ON c.ContactID = a.AddressID
WHERE c.LastName LIKE @EmpLName;
GO
EXEC FindEmployee @EmpLName = 'Barb';
GO
复制代码
USE AdventureWorks;
GO
CREATE PROCEDURE FindEmployee @EmpLName varchar(20)
AS
SELECT @EmpLName = RTRIM(@EmpLName) + '%';
SELECT c.FirstName, c.LastName, a.City
FROM Person.Contact c JOIN Person.Address a ON c.ContactID = a.AddressID
WHERE c.LastName LIKE @EmpLName;
GO
EXEC FindEmployee @EmpLName = 'Barb';
下面是结果集:
复制代码
FirstName LastName City
---------- ----------------------------------------
Angela Barbariol Snohomish
David Barber Snohomish
(2 row(s) affected)
使用 LIKE 的模式匹配
LIKE 支持 ASCII 模式匹配和 Unicode 模式匹配。如果所有参数(match_expression、pattern 和 escape_character,如果存在)均为 ASCII 字符数据类型,则执行 ASCII 模式匹配。如果任何一个参数为 Unicode 数据类型,则所有参数都将转换为 Unicode,并执行 Unicode 模式匹配。当 Unicode 数据(nchar 或 nvarchar 数据类型)与 LIKE 一起使用时,尾随空格有意义;但对非 Unicode 数据,尾随空格则没有意义。Unicode LIKE 与 SQL-92 标准兼容。ASCII LIKE 与 SQL Server 的早期版本兼容。
下面的一系列示例显示 ASCII LIKE 模式匹配与 Unicode LIKE 模式匹配所返回的行之间的差异。
复制代码
-- ASCII pattern matching with char column
CREATE TABLE t (col1 char(30));
INSERT INTO t VALUES ('Robert King');
SELECT *
FROM t
WHERE col1 LIKE '% King' -- returns 1 row
-- Unicode pattern matching with nchar column
CREATE TABLE t (col1 nchar(30));
INSERT INTO t VALUES ('Robert King');
SELECT *
FROM t
WHERE col1 LIKE '% King' -- no rows returned
-- Unicode pattern matching with nchar column and RTRIM
CREATE TABLE t (col1 nchar (30));
INSERT INTO t VALUES ('Robert King');
SELECT *
FROM t
WHERE RTRIM(col1) LIKE '% King' -- returns 1 row
注意:
LIKE 比较受排序规则影响。有关详细信息,请参阅 COLLATE (Transact-SQL)。
使用 % 通配符
如果指定 LIKE '5%' 符号,则数据库引擎 将搜索后跟零个或多个任意字符的数字 5。
复制代码
USE AdventureWorks;
GO
SELECT Name
FROM sys.system_views
WHERE Name LIKE 'dm%';
GO
若要查看所有非动态管理视图的对象,请使用 NOT LIKE 'dm%'。如果共有 32 个对象且 LIKE 找到 13 个与模式匹配的名称,则 NOT LIKE 将找到 19 个与 LIKE 模式不匹配的对象。
使用 LIKE '[^d][^m]%' 之类的模式不一定每次找到的名称都相同。可能仅找到 14 名称(而不是 19 个),除了动态管理视图名称外,所有以 d 开始或第二个字母为 m 的名称也都将从结果中消除。这是因为用反向通配符匹配字符串是分步骤进行计算的,一次一个通配符。如果在计算过程中任一环节匹配失败,那么就会将其消除。
将通配符作为文字使用
可以将通配符模式匹配字符作为文字字符使用。若要将通配符作为文字字符使用,请将通配符放在方括号中。下表显示了几个使用 LIKE 关键字和 [ ] 通配符的示例。
结果值
如果 match_expression 与指定的 pattern 相匹配,则 LIKE 返回 TRUE。
示例
A. 使用带 % 通配符的 LIKE
以下示例在 Contact 表中查找区号不是 415 的所有电话号码。
复制代码
USE AdventureWorks;
GO
SELECT FirstName, LastName, Phone
FROM Person.Contact
WHERE phone LIKE '415%'
ORDER by LastName;
GO
下面是结果集:
复制代码
FirstName LastName phone
----------------- ---------------- ------------
Ruben Alonso 415-555-0124
Shelby Cook 415-555-0121
Karen Hu 415-555-0114
John Long 415-555-0147
David Long 415-555-0123
Gilbert Ma 415-555-0138
Meredith Moreno 415-555-0131
Alexandra Nelson 415-555-0174
Taylor Patterson 415-555-0170
Gabrielle Russell 415-555-0197
Dalton Simmons 415-555-0115
(11 row(s) affected)
B. 使用带 % 通配符的 NOT LIKE
以下示例在 Contact 表中查找区号不是 415 的所有电话号码。
复制代码
USE AdventureWorks;
GO
SELECT FirstName, LastName, Phone
FROM Person.Contact
WHERE Phone NOT LIKE '415%' AND FirstName = 'Gail'
ORDER BY LastName;
GO
复制代码
USE tempdb;
GO
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'mytbl2')
DROP TABLE mytbl2;
GO
USE tempdb;
GO
CREATE TABLE mytbl2
(
c1 sysname
);
GO
INSERT mytbl2 VALUES ('Discount is 10-15% off');
INSERT mytbl2 VALUES ('Discount is .10-.15 off');
GO
SELECT c1
FROM mytbl2
WHERE c1 LIKE '%10-15!% off%' ESCAPE '!';
GO
复制代码
USE AdventureWorks;
GO
SELECT ContactID, FirstName, LastName
FROM Person.Contact
WHERE FirstName LIKE '[CS]heryl';
GO
以下示例查找姓氏为 Zheng 或 Zhang 的 Contacts 行。
复制代码
USE AdventureWorks;
GO
SELECT LastName, FirstName, Phone
FROM Person.Contact
WHERE LastName LIKE 'Zh[ae]ng'
ORDER BY LastName ASC, FirstName ASC;
GO