1

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

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

我编写了以下有效的函数,但它看起来很复杂,所以我一定做错了。关于不同方法或如何使其执行的任何想法?

顺便说一句,数据库对我来说是只读的,所以我不能对其进行全文索引,所有者也不会这样做。

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');
4

3 回答 3

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');
于 2013-04-02T19:02:23.393 回答
0

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

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

更新:

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

于 2013-04-02T18:40:10.557 回答
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) = ' ';
于 2013-04-03T05:27:09.910 回答