2016-11-02 4 views
-1

Моя цель - создать запрос, который будет искать результаты, относящиеся к определенному ключевому слову.Заменить каждый альфа-символ на себя + подстановочный знак в строке SQL Server

Скажем, в базе данных у нас было слово cat.

Независимо от того, является ли пользователь типом C a t, C.A.T. или Cat я хочу найти результат, связанный с поиском тех пор, как буквенно-цифровые символы в правильной последовательности, все, что имеет значение

Say в базе данных у нас есть эти 4 записей

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

If user types in 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 не означает, что не может быть никаких буквенно-цифровых символов между C и A.
На самом деле это означает, что должно быть по крайней мере одно не альфа-цифровое значение между C и A.

Кроме того, он также вернет неправильные значения - будет возвращено значение 'c u a s e t '.

Вы должны изменить ваш где положение на что-то вроде этого:

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