2016-11-02 57 views
-1

我的目标是创建一个将搜索与特定关键字相关的结果的查询。在字符串中替换每个字母字符与自身+通配符SQL Server

在数据库中说我们有猫这个词。

无论用户是否键入C a t,C.A.T.或猫,我想找到相关的搜索,只要字母数字字符是正确的顺序是所有数据库中的重要

说,我们有这4个记录

cat 
c/a/t 
c.a.t 
c. at 

如果结果用户输入C#$*(&A T我想获得全部4个结果。

我到目前为止在我的查询中所写的内容是一个从输入字符串中去除任何非字母数字字符的函数。

我能做些什么来替代每个字母数字字符,并在最后添加通配符?

对于每一个字母字符我的投入将类似于此

C%[^a-zA-Z0-9]%A%[^a-zA-Z0-9]%T%[^a-zA-Z0-9]% 

回答

0

你可以递归通过你(清洗)搜索字符串,并每个字母添加你想表达的。在我的例子中,如果我理解正确,@builtString应该是你想进一步使用的。

declare @cleanSearch as nvarchar(10) = 'CAT' 
declare @builtString as nvarchar(100) = '' 

WHILE LEN(@cleanSearch) > 0 -- loop until you deplete the search string 
    BEGIN 
     SET @builtString = @builtString + substring(@cleanSearch,1,1) + '%[^a-zA-Z0-9]%' -- append the letter plus regular expression 
      SET @cleanSearch = right(@cleanSearch, len(@cleanSearch) - 1)    -- remove first letter of the search string 
    END 

SELECT @builtString --will look like C%[^a-zA-Z0-9]%A%[^a-zA-Z0-9]%T%[^a-zA-Z0-9]% 
SELECT @cleanSearch [email protected] is now empty 
1

实际上,该搜索字符串将只从该表中返回一条记录:该行与'c.a.t '

这是因为表达式C%[^a-zA-Z0-9]%A并不意味着在CA之间不能有任何字母数字字符。
它实际上意味着至少应该有一个非字母数字值在CA之间。

此外,它还会返回不正确的值 - 将返回一个值,如'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,at之间的数字字符,第二行将解析为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

而且因为我有一些空闲时间,这里是一个脚本来创建两个likenot 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