Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 检查文本中是否存在所有单词片段_Sql Server_Sql Server 2008 R2 - Fatal编程技术网

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

Sql server 检查文本中是否存在所有单词片段,sql-server,sql-server-2008-r2,Sql Server,Sql Server 2008 R2,我想检查所有给定单词片段是否以任何顺序存在于给定文本中 这些片段由web应用程序用户以单个字符串形式提供,字符串之间用空格分隔,如“abc xyz kj”。它们存在于“mn kj qabc pc xyzw”中,但不存在于“mn kj qabc pc xyw”中 我写了下面的函数,它可以工作,但是看起来很复杂,所以我一定是做错了。对不同的方法或如何使其发挥作用有何想法 顺便说一句,数据库对我来说是只读的,所以我不能对它进行全文索引,所有者也不会这样做 create function dbo.tem

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

这些片段由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');
创建函数dbo.tem\u fragmentos(
@texto varchar(最大值),
@fragmentos varchar(最大值)
)
返回位为
开始
声明
@inicio整数=1,
@fim整数,
@fragmento varchar(最大值);
设置@fragmentos=ltrim(rtrim(@fragmentos));
而charindex('',@fragmentos)>0
设置@fragmentos=replace(@fragmentos,,“”);

虽然@inicio我假设您的文本存在于db表中,否则您就不会让db服务器来做这项工作。那么,为什么不让你的应用程序打破空格上的字符串,构建动态SQL,比如:

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


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

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

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


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

我将这样做。不确定它是否更复杂

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');
创建函数dbo.tem\u fragmentos
(
@texto varchar(最大值),
@fragmentos varchar(最大值)
)
返回位为
开始
声明@table表(fragmentos Varchar(Max))
设置@fragmentos=Ltrim(Rtrim(@fragmentos))
而@fragmentos“
开始
插入@table(fragmentos)
选择左侧(@fragmentos,Charindex('',@fragmentos+'')-1)
设置@fragmentos=Ltrim(右(@fragmentos,Len(@fragmentos)-(Charindex(“”,@fragmentos+“”)-1));
结束
如果存在(选择1
来自@table t
其中@texto不象“%”+fragmentos+“%”)
开始
返回0;
终点
返回1;
结束;
选择dbo.tem_fragmentos('clodoaldo pinto neto','clo cl nto pinto');

我就是这样做的。不确定它是否更复杂

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');
创建函数dbo.tem\u fragmentos
(
@texto varchar(最大值),
@fragmentos varchar(最大值)
)
返回位为
开始
声明@table表(fragmentos Varchar(Max))
设置@fragmentos=Ltrim(Rtrim(@fragmentos))
而@fragmentos“
开始
插入@table(fragmentos)
选择左侧(@fragmentos,Charindex('',@fragmentos+'')-1)
设置@fragmentos=Ltrim(右(@fragmentos,Len(@fragmentos)-(Charindex(“”,@fragmentos+“”)-1));
结束
如果存在(选择1
来自@table t
其中@texto不象“%”+fragmentos+“%”)
开始
返回0;
终点
返回1;
结束;
选择dbo.tem_fragmentos('clodoaldo pinto neto','clo cl nto pinto');

听起来像是一个通配符
类似的搜索应该适合您:

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) = ' ';
declare@texto varchar(max)='mn kj q abc pc xyzw',
@fragmentos varchar(最大)='abc xyz kj'
/*
是='mn kj qabc pc xyzw'
否='mn kj qabc pc xyw'
*/
--使用你自己的号码表
声明@number表(n int-identity(1,1)主键集群,x char(1)null);
插入@number(x)
从master..spt\u值中选择top 1000 null
选择[IsMatch]=min(类似于“%”文本的“%”子字符串(@fragmentos,n,charindex(“,@fragmentos+”,n)-n)-n)+“%”时的大小写为1,然后为0结束)
从@number开始

其中n听起来像是通配符
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) = ' ';
declare@texto varchar(max)='mn kj q abc pc xyzw',
@fragmentos varchar(最大)='abc xyz kj'
/*
是='mn kj qabc pc xyzw'
否='mn kj qabc pc xyw'
*/
--使用你自己的号码表
声明@number表(n int-identity(1,1)主键集群,x char(1)null);
插入@number(x)
从master..spt\u值中选择top 1000 null
选择[IsMatch]=min(类似于“%”文本的“%”子字符串(@fragmentos,n,charindex(“,@fragmentos+”,n)-n)-n)+“%”时的大小写为1,然后为0结束)
从@number开始

我这么做已经很久了。但这次我不会动态构建它,因为整个查询非常复杂,我想保持理智。很高兴了解TVP。据我所知,有必要创建一个类型来使用它,但我无法写入数据库。我已经这样做了很久了。但这次我不会动态构建它,因为整个查询非常复杂,我想保持理智。很高兴了解TVP。据我所知,有必要创建一个类型来使用它,但我无法写入数据库。