Соответствие нескольких вариантов ввода одной строки SQL - PullRequest
1 голос
/ 05 октября 2011

Я хотел бы знать после много поиска, как я сопоставил бы различные варианты ввода для одной строки SQL, используя стандартный TSQL.Вот сценарий:

В моей строке sql есть следующий текст: I love

Затем у меня есть следующие 3 входа, каждый из которых должен возвращать соответствие этой строке:

" Я хочу сказать вам, что мы все любим StackOverflow"

" Я Я полностью в love с StackOverflow "

" I действительно love StackOverflow "

Как видите, я выделил причинудля матча, чтобы понять, почему они совпадают.I в I'm тоже намеренно совпадают, поэтому было бы хорошо, если бы мы могли включить это в совпадения.

Я думал о разбиении входной строки, которую я сделал, используя следующий TSQL:

-- Create a space delimited string for testing
declare @str varchar(max)
select @str = 'I want to tell you we all love StackOverflow'
-- XML tag the string by replacing spaces with </x><x> tags
declare @xml xml
select @xml = cast('<x><![CDATA['+ replace(@str,' ',']]></x><x><![CDATA[') + ']]></x>' as xml)
-- Finally select values from nodes <x> and trim at the same time
select ltrim(rtrim(mynode.value('.[1]', 'nvarchar(12)'))) as Code
from (select @xml doc) xx
cross apply doc.nodes('/x') (mynode)

Это дает мне все слова в виде отдельных строк, но тогда я не могу понять, как выполнить запрос на их соответствие.

Поэтому любая помощь с этой точки или любые альтернативные способы сопоставления по мере необходимостибудет более чем признателен!

ОБНОВЛЕНИЕ:

@ freefaller указал мне маршрут RegEx и создал функцию, которую я смог продвинуть немного вперед,поэтому +1 @freefaller, однако теперь мне нужно знать, как заставить его просматривать все строки моей таблицы, а не жестко запрограммированный ввод «Я люблю». Теперь у меня есть следующие операторы выбора:

SELECT * FROM dbo.FindWordsInContext('i love','I want to tell you we all love StackOverflow',30)
SELECT * FROM dbo.FindWordsInContext('i love','I''m totally in love with StackOverflow',30)
SELECT * FROM dbo.FindWordsInContext('i love','I really love StackOverflow',30)

Вышеприведенное возвращает мне количество совпадений и совпадение контекста строки, поэтому первое выделенное выше возвращает:

Hits    Context
1       ...I want to tell you we all love StackOv...

Итак, основываясь на фактетеперь у нас есть вышесказанное, может кто-нибудь сказать мне, как заставить эту функцию просматривать все строки на совпадения и затем возвращать строку / строки, которые имеют совпадение?

Ответы [ 2 ]

1 голос
/ 06 октября 2011

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

Сначала включите SQL-CLR на вашем сервере, если он еще не доступен (вам необходимо быть системным администратором):

--Enables CLR Integration
exec sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO

Тогда вам нужно будет создать сборку в SQL (не забудьте изменить путь с D:\SqlRegEx.dll и использовать набор разрешений SAFE, так как это наиболее ограниченный и безопасный набор разрешений, но он не будет подробно здесь.):

CREATE ASSEMBLY [SqlRegEx] FROM 'D:\SqlRegEx.dll' WITH PERMISSION_SET = SAFE

Теперь создайте реальную функцию, которую вы будете вызывать:

CREATE FUNCTION [dbo].[RegexMatch]
(@Input NVARCHAR(MAX), @Pattern NVARCHAR(MAX), @IgnoreCase BIT)
RETURNS BIT
AS EXTERNAL NAME SqlRegEx.[SqlClrTools.SqlRegEx].RegExMatch

Наконец, чтобы завершить и ответить на мой собственный вопрос, мы можем запустить следующий TSQL:

SELECT *
FROM your_table
WHERE dbo.RegexMatch(@search, REPLACE(your_field, ' ', '.*?'), 1) = 1
SELECT *
FROM your_table
WHERE dbo.RegexMatch(@search, REPLACE(REVERSE(your_field), ' ', '.*?'), 1) = 1

Надеюсь, это поможет кому-то в будущем найти простой вариант поиска.

1 голос
/ 05 октября 2011

Одним из вариантов будет использование регулярных выражений через объекты SQLCLR , как описано здесь .

Я никогда сам не создавал объекты SQLCLR, поэтому не могу комментировать простоту этого метода.Однако я большой поклонник регулярных выражений и рекомендую их использовать для большинства текстовых поисков / манипуляций

Редактировать : В ответ на комментарий у меня нет опыта работы с SQLCLR, но я предполагаю, чтоВы работаете, что-то вроде следующего простого непроверенного TSQL может работать ...

SELECT *
FROM mytable
WHERE dbo.RegexMatch(@search, REPLACE(myfield, ' ', '.*?')) = 1
...