检查文本中是否存在所有单词片段

时间:2013-04-02 18:32:21

标签: sql-server sql-server-2008-r2

我想检查给定文本中的任何顺序是否存在所有给定的单词片段。

片段由Web应用程序用户以单个字符串提供,由'abc xyz kj'之类的空格分隔。它们存在于'mn kj qabc pc xyzw'中,但在'mn kj qabc pc xyw'中不存在。

我编写了以下功能,但它看起来很复杂,所以我一定做错了。关于不同方法的任何想法或如何使其表现?

BTW数据库只为我读取,因此我无法对其进行全文索引,而且所有者也不会这样做。

create function dbo.tem_fragmentos(
    @texto varchar(max), 
    @fragmentos varchar(max)
)
returns bit as
begin
    declare 
        @inicio integer = 1,
        @fim integer,
        @fragmento varchar(max);

    set @fragmentos = ltrim(rtrim(@fragmentos));
    while charindex('  ', @fragmentos) > 0
        set @fragmentos = replace(@fragmentos, '  ', ' ');

    while @inicio <= len(@fragmentos) begin
        set @fim = charindex(' ', @fragmentos, @inicio + 1);
        if @fim = 0 set @fim = len(@fragmentos) + 1;
        set @fragmento = substring(@fragmentos, @inicio, @fim - @inicio);
        if charindex(@fragmento, @texto) = 0 return 0;
        set @inicio = @fim + 1;
    end -- while
    return 1;
end;

select dbo.tem_fragmentos('clodoaldo pinto neto', ' clo cl nto pinto');

3 个答案:

答案 0 :(得分:1)

我就是这样做的。不确定它是不是很复杂......

Create  Function dbo.tem_fragmentos
        (
            @texto varchar(max), 
            @fragmentos varchar(max)
        )
Returns Bit As
Begin   
        Declare @table Table (fragmentos Varchar(Max))
        Set     @fragmentos = Ltrim(Rtrim(@fragmentos))

        While @fragmentos <> ''
        Begin
                Insert  @table (fragmentos)
                Select  Left(@fragmentos,Charindex(' ',@fragmentos+' ')-1)

                Set     @fragmentos = Ltrim(Rtrim(Right(@fragmentos,Len(@fragmentos)-(Charindex(' ',@fragmentos+' ')-1))));
        end

        If      Exists (Select 1
                        From @table t
                        Where @texto Not Like '%' + fragmentos + '%')
        Begin
                Return 0;
        End
        Return 1;
End;

Select  dbo.tem_fragmentos('clodoaldo pinto neto', ' clo cl nto pinto');

答案 1 :(得分:0)

我假设你的文本存在于db表中,否则你不会让db服务器完成工作。那么,为什么不让你的应用程序在空格上打破字符串并构建动态SQL,如:

select *
from MyTable 
where charindex('abc', MyColumn) > 0
    and charindex('xyz', MyColumn) > 0
    and charindex('kj', MyColumn) > 0

<强>更新

如果您不想使用动态SQL,我会将输入拆分为应用程序中的单词,然后使用表值参数(TVP)将单词列表传递给查询。然后,这是一个简单的左连接,以确定它们是否匹配。

答案 2 :(得分:0)

听起来像通配符LIKE搜索应该适合您:

declare @texto varchar(max) = 'mn kj q abc pc xyzw', 
        @fragmentos varchar(max) = 'abc xyz kj'
/*
yes = 'mn kj qabc pc xyzw' 
 no = 'mn kj qabc pc xyw'
*/


--use your own number table
declare @number table (n int identity(1,1) primary key clustered, x char(1) null);
insert into @number(x)
    select top 1000 null from master..spt_values


select  [IsMatch] = min(case when @texto like '%'+substring(@fragmentos, n, charindex(' ', @fragmentos + ' ', n) - n)+'%' then 1 else 0 end)
from    @number
where   n <= datalength(@fragmentos)+1 and 
        substring(' ' + @fragmentos, N, 1) = ' ';