Найти строки, содержащие слова с разделителями, в параметре nvarchar - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть процедура, которая выбирает смещение строк из таблицы:

SELECT * --table contains ID and Name columns
FROM Names
ORDER BY ID
OFFSET @Start ROWS
FETCH NEXT @Length ROWS ONLY

В дополнение к параметрам @Start и @Length процедура также получает параметр @SearchValue NVARCHAR(255). @SearchValue содержит строку значений, разделенных пробелом, например '1 ik mi' или 'Li 3'.

Мне нужно запросить каждую запись, содержащую все эти значения. Таким образом, если @SearchValue равно '1 ik mi', он должен возвращать любые записи, которые содержат все три значения: «1», «mi» и «ik». Еще один способ понять это, перейдя здесь , выполнить поиск в таблице (попробуйте поискать 00 eer 7) и наблюдать отфильтрованные результаты.

У меня есть свобода изменять разделитель или запускать некоторые функция (в моем случае C#), которая может форматировать массив этих слов.

Ниже приведены наши неудачные попытки (мы еще не пытались реализовать его с помощью OFFSET):

Select ID, Name
From Names
Where Cast(ID as nvarchar(255)) in (Select value from string_split(@SearchValue, ' ')) AND 
Name in (Select value from string_split(@SearchValue, ' '))
SELECT ID, Name
FROM Names
WHERE @SearchValueLIKE '% ' + CAST(ID AS nvarchar(20)) + ' %' AND
@SearchValueLIKE '% ' + Name + ' %';

Мы использовали документы Microsoft для string_split для идеи выше.

Завтра я попытаюсь реализовать это решение , но мне интересно, есть ли другой способ сделать это в случае, если один не работает. Спасибо!

1 Ответ

0 голосов
/ 02 апреля 2020

Лучше всего будет использовать индекс FULL TEXT. Это то, для чего они созданы.

Сказав, что вы можете обойти это .. НО! Вы собираетесь создать запрос, чтобы сделать это. Вы можете либо создать запрос в C# и запустить его в базе данных, либо создать его в базе данных. Тем не менее, вы никогда не сможете оптимизировать запрос очень хорошо, потому что пользователи, которые являются пользователями, могут добавлять в поиск все виды мусора, за которым вам нужно следить, что, очевидно, является топикой c для другого обсуждения. .

В приведенном ниже решении используется sp_execute sql, поэтому вам придется следить за SQL инъекцией (прежде чем кто-то другой разберет весь этот ответ, чтобы указать SQL инъекцию ):

DROP TABLE #Cities;

CREATE TABLE #Cities(id INTEGER IDENTITY PRIMARY KEY, [Name] VARCHAR(100));

INSERT INTO #Cities ([Name]) VALUES
('Cooktown'),
('South Suzanne'),
('Newcastle'),
('Leeds'),
('Podunk'),
('Udaipur'),
('Delhi'),
('Murmansk');

DECLARE @SearchValue VARCHAR(20) = 'ur an rm';
DECLARE @query NVARCHAR(1000);

SELECT @query = COALESCE(@query + '%'' AND [Name] LIKE ''%', '') + value
FROM (Select value from string_split(@SearchValue, ' ')) a;

SELECT @query = 'SELECT * FROM #Cities WHERE [Name] LIKE ''%' + @query + '%''';

EXEC sp_executesql @query;
...