我在 SQL Server 2008 环境中。
我试图在WHERE
子句中使用模式匹配来查找某个列的值包含非字母数字、下划线、破折号、句点或空格的字符的行。
这是我的代码和示例数据,但我没有得到预期的结果。
在示例数据中,我想返回第 7、8、9 和 12 行,但我得到的是第 5 行和第 6 行。
如果这不是实现目标的最佳方式,我愿意听取其他方法。
我不在一个可以实现正则表达式的环境中,所以我的解决方案仅限于开箱即用的功能。
CREATE TABLE PATTERN_TEST
(
ID INT NOT NULL,
STRING NVARCHAR(40) NOT NULL
)
INSERT INTO PATTERN_TEST
SELECT 1, 'string' UNION
SELECT 2, 'STRING' UNION
SELECT 3, 'string space' UNION
SELECT 4, 'STRING SPACE' UNION
SELECT 5, 'string-dash' UNION
SELECT 6, 'string-dash space' UNION
SELECT 7, 'string "otherchar"' UNION
SELECT 8, 'string "other char"' UNION
SELECT 9, '"string"' UNION
SELECT 10, 'string_underscore' UNION
SELECT 11, 'string_underscore space' UNION
SELECT 12, '"'
;
SELECT * FROM PATTERN_TEST WHERE STRING LIKE '%[^a-zA-Z0-9_ -.]%';
这也将起作用:
在rextester.com测试
唯一的区别是破折号 (
-
) 放在[...]
模式的末尾。它与破折号字符的特殊含义有关(A-Z
被解释为“从到的任何字符”A
Z
)。在您的模式中,最后三个字符(空格破折号:)
-.
被解释为“从空格()到点(
.
)的任何字符”,结果不是想要的/预期的。你也可以逃避破折号:
请注意,尽管使用
ESCAPE
可能会对基数估计产生不利影响。有关详细信息,请参阅 MSDN 文档
LIKE
:需要明确的是:特殊字符在用作非特殊字符时需要转义。在 [] 中,三个 (^, -, ]) 是特殊的。把破折号放在最后更像是一个黑客。
在您无法利用被要求使用的工具的全部功能集的情况下,总是很糟糕。CLR 绝对是正确执行此操作的方法。
如果我理解正确,我认为您应该能够编写一个函数以在传递的字符串包含您的一个无效字符时返回一个空集并用于
CROSS APPLY
去除无效结果。