实际上,该搜索字符串将只从该表中返回一条记录:该行与'c.a.t '
。
这是因为表达式C%[^a-zA-Z0-9]%A
并不意味着在C
和A
之间不能有任何字母数字字符。
它实际上意味着至少应该有一个非字母数字值在C
和A
之间。
此外,它还会返回不正确的值 - 将返回一个值,如'c u a s e t '
。
你需要改变你的where子句来是这样的:
WHERE column LIKE '%C%A%T%'
AND column NOT LIKE '%C%[a-zA-Z0-9]%A%[a-zA-Z0-9]%T%'
这样,如果你有正确的顺序cat
,第一行会解析为true
,如果没有其他α - c
,a
和t
之间的数字字符,第二行将解析为true
。
下面是测试脚本,在这里你可以为自己明白我的意思:
DECLARE @T AS TABLE
(
a varchar(20)
)
INSERT INTO @T VALUES
('cat'),
('c/a/t'),
('c.a.t '),
('c. at'),
('c u a s e t ')
-- Incorrect where clause
SELECT *
FROM @T
WHERE a LIKE 'C%[^a-zA-Z0-9]%A%[^a-zA-Z0-9]%T%[^a-zA-Z0-9]%'
-- correct where clause
SELECT *
FROM @T
WHERE a LIKE '%C%A%T%'
AND a NOT LIKE '%C%[a-zA-Z0-9]%A%[a-zA-Z0-9]%T%'
你也可以看到它在行动this link。
而且因为我有一些空闲时间,这里是一个脚本来创建两个like
和not like
从输入的字符串模式:
DECLARE @INPUT varchar(100) = '@*# c %^&# a ^&*$&* t (*&(%[email protected]#$'
DECLARE @Index int = 1,
@CurrentChar char(1),
@Like varchar(100),
@NotLike varchar(100) = '%'
WHILE @Index < LEN(@Input)
BEGIN
SET @CurrentChar = SUBSTRING(@INPUT, @Index, 1)
IF PATINDEX('%[^a-zA-Z0-9]%', @CurrentChar) = 0
BEGIN
SET @NotLike = @NotLike + @CurrentChar + '%[a-zA-Z0-9]%'
END
SET @Index = @Index + 1
END
SELECT @NotLike = LEFT(@NotLike, LEN(@NotLike) - 12),
@Like = REPLACE(@NotLike, '%[a-zA-Z0-9]%', '%')
SELECT *
FROM @T
WHERE a LIKE @Like
AND a NOT LIKE @NotLike