En développant l'idée d'Ishmael, ce n'est pas la solution finale, mais je pense que c'est une bonne façon de commencer.
Il faut d'abord récupérer la liste des mots qui ont été récupérés avec le moteur de texte intégral :
declare @SearchPattern nvarchar(1000) = 'FORMSOF (INFLECTIONAL, " ' + @SearchString + ' ")'
declare @SearchWords table (Word varchar(100), Expansion_type int)
insert into @SearchWords
select distinct display_term, expansion_type
from sys.dm_fts_parser(@SearchPattern, 1033, 0, 0)
where special_term = 'Exact Match'
Il y a déjà pas mal de choses sur lesquelles on peut s'étendre, par exemple le modèle de recherche est assez basique; il existe également probablement de meilleures façons de filtrer les mots dont vous n'avez pas besoin, mais cela vous donne au moins une liste de mots souches, etc. qui seraient mis en correspondance par une recherche en texte intégral.
Une fois que vous avez obtenu les résultats dont vous avez besoin, vous pouvez utiliser RegEx pour analyser le jeu de résultats (ou de préférence seulement un sous-ensemble pour l'accélérer, bien que je n'aie pas encore trouvé un bon moyen de le faire). Pour cela, j'utilise simplement deux boucles while et un tas de tables et de variables temporaires :
declare @FinalResults table
while (select COUNT(*) from @PrelimResults) > 0
begin
select top 1 @CurrID = [UID], @Text = Text from @PrelimResults
declare @TextLength int = LEN(@Text )
declare @IndexOfDot int = CHARINDEX('.', REVERSE(@Text ), @TextLength - dbo.RegExIndexOf(@Text, '\b' + @FirstSearchWord + '\b') + 1)
set @Text = SUBSTRING(@Text, case @IndexOfDot when 0 then 0 else @TextLength - @IndexOfDot + 3 end, 300)
while (select COUNT(*) from @TempSearchWords) > 0
begin
select top 1 @CurrWord = Word from @TempSearchWords
set @Text = dbo.RegExReplace(@Text, '\b' + @CurrWord + '\b', '<b>' + SUBSTRING(@Text, dbo.RegExIndexOf(@Text, '\b' + @CurrWord + '\b'), LEN(@CurrWord) + 1) + '</b>')
delete from @TempSearchWords where Word = @CurrWord
end
insert into @FinalResults
select * from @PrelimResults where [UID] = @CurrID
delete from @PrelimResults where [UID] = @CurrID
end
Plusieurs remarques :
1. Les boucles while imbriquées ne sont probablement pas le moyen le plus efficace de le faire, mais rien d'autre ne vient à l'esprit. Si je devais utiliser des curseurs, ce serait essentiellement la même chose ?
2. @FirstSearchWord
ici fait référence à la première instance dans le texte de l'un des mots de recherche d'origine, donc essentiellement le texte que vous remplacez ne figurera que dans le résumé. Encore une fois, c'est une méthode assez basique, une sorte d'algorithme de recherche de cluster de texte serait probablement utile.
3. Pour obtenir RegEx en premier lieu, vous avez besoin de fonctions CLR définies par l'utilisateur.