Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.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_Tsql_String - Fatal编程技术网

Sql server SQL Server字符串操作-拆分搜索词并生成新字符串

Sql server SQL Server字符串操作-拆分搜索词并生成新字符串,sql-server,tsql,string,Sql Server,Tsql,String,我目前正在为我们的网站构建一个基于SQL Server全文索引的搜索功能,需要将用户的输入拆分为一组搜索词。一旦这些术语被拆分,我就需要将它们重新构建成一个字符串,其中包含将针对CONTAINS()或CONTAINSTABLE()全文查询执行的查询 例如,如果用户输入 Jon Sidnell 在我们的搜索框中,我希望能够将该字符串转换为以下内容: '("jon*" OR FORMSOF(THESAURUS, jon) OR FORMSOF(INFLECTIONAL, jon)) OR ("s

我目前正在为我们的网站构建一个基于SQL Server全文索引的搜索功能,需要将用户的输入拆分为一组搜索词。一旦这些术语被拆分,我就需要将它们重新构建成一个字符串,其中包含将针对CONTAINS()或CONTAINSTABLE()全文查询执行的查询

例如,如果用户输入

Jon Sidnell
在我们的搜索框中,我希望能够将该字符串转换为以下内容:

'("jon*" OR FORMSOF(THESAURUS, jon) OR FORMSOF(INFLECTIONAL, jon)) OR 
("sidnell*" OR FORMSOF(THESAURUS, sidnell) OR FORMSOF(INFLECTIONAL, sidnell))'
SET NOCOUNT ON

DECLARE @sampleString VARCHAR(500)
SET @sampleString = 'Jon Sidnell Rocks'

DECLARE @delimiter VARCHAR(20);
SET @delimiter = ' '

DECLARE @SplitResults TABLE (
    POSITION INT, 
    VALUE VARCHAR(8000), 
    fUsed BIT DEFAULT 0)

INSERT INTO @SplitResults ( POSITION, VALUE )
SELECT * FROM dbo.ufn_SplitString(@sampleString, @delimiter)

--Set up a simple loop instead of having to open up a cursor
DECLARE @Value VARCHAR(8000);
DECLARE @Position INT;
SELECT @Value = q.VALUE, @Position = q.Position
FROM (SELECT TOP 1 VALUE, Position FROM @SplitResults WHERE fUsed = 0)q

DECLARE @SearchString VARCHAR(8000)
WHILE @@ROWCOUNT <> 0 AND @Value IS NOT NULL
BEGIN

    IF @Position = 1
    BEGIN
        SET @SearchString = '("' + @Value + '*" OR FORMSOF(THESAURUS, '+ @Value +') OR FORMSOF(INFLECTIONAL, ' + @Value + '))'
    END
    ELSE
    BEGIN
        SET @SearchString = @SearchString + ' OR ("' + @Value + '*" OR FORMSOF(THESAURUS, '+ @Value +') OR FORMSOF(INFLECTIONAL, ' + @Value + '))'
    END

    --Update record so we know we used it
    UPDATE @SplitResults SET fUsed = 1 
    WHERE Position = @Position AND VALUE = @Value

    --Get Next Value to Work With
    SELECT @Value = q.VALUE, @Position = q.Position
    FROM (SELECT TOP 1 VALUE, Position FROM @SplitResults WHERE fUsed = 0)q
END

PRINT @SearchString;

SET NOCOUNT OFF;
显然,如果用户输入中有三个单词,那么将有三组“通配符、同义词表或屈折”术语

作为一个T-SQL新手(不是新手,但肯定不是大师!),我不确定最好的方法是什么。我在谷歌上搜索过,虽然我遇到了一些有助于初始字符串拆分的东西,但我并不知道如何最好地使用拆分表示来构造结果字符串


有人能帮忙吗?

我不知道这是否是解决问题的最有效方法,但我想到的一个想法是封装逻辑,将输入字符串拆分为表值函数

调用函数并将结果存储到表变量中

迭代表变量,并将拆分的字符串连接到用于搜索的最终字符串中

我没有在这里包含函数的代码(为简洁起见),但在我的例子中,我的函数接受要拆分的字符串和分隔符来拆分字符串,并返回具有以下结构的表:
Position INT,Value VARCHAR(8000)

一旦功能到位,您可以将其合并,类似于以下内容:

'("jon*" OR FORMSOF(THESAURUS, jon) OR FORMSOF(INFLECTIONAL, jon)) OR 
("sidnell*" OR FORMSOF(THESAURUS, sidnell) OR FORMSOF(INFLECTIONAL, sidnell))'
SET NOCOUNT ON

DECLARE @sampleString VARCHAR(500)
SET @sampleString = 'Jon Sidnell Rocks'

DECLARE @delimiter VARCHAR(20);
SET @delimiter = ' '

DECLARE @SplitResults TABLE (
    POSITION INT, 
    VALUE VARCHAR(8000), 
    fUsed BIT DEFAULT 0)

INSERT INTO @SplitResults ( POSITION, VALUE )
SELECT * FROM dbo.ufn_SplitString(@sampleString, @delimiter)

--Set up a simple loop instead of having to open up a cursor
DECLARE @Value VARCHAR(8000);
DECLARE @Position INT;
SELECT @Value = q.VALUE, @Position = q.Position
FROM (SELECT TOP 1 VALUE, Position FROM @SplitResults WHERE fUsed = 0)q

DECLARE @SearchString VARCHAR(8000)
WHILE @@ROWCOUNT <> 0 AND @Value IS NOT NULL
BEGIN

    IF @Position = 1
    BEGIN
        SET @SearchString = '("' + @Value + '*" OR FORMSOF(THESAURUS, '+ @Value +') OR FORMSOF(INFLECTIONAL, ' + @Value + '))'
    END
    ELSE
    BEGIN
        SET @SearchString = @SearchString + ' OR ("' + @Value + '*" OR FORMSOF(THESAURUS, '+ @Value +') OR FORMSOF(INFLECTIONAL, ' + @Value + '))'
    END

    --Update record so we know we used it
    UPDATE @SplitResults SET fUsed = 1 
    WHERE Position = @Position AND VALUE = @Value

    --Get Next Value to Work With
    SELECT @Value = q.VALUE, @Position = q.Position
    FROM (SELECT TOP 1 VALUE, Position FROM @SplitResults WHERE fUsed = 0)q
END

PRINT @SearchString;

SET NOCOUNT OFF;

如果您使用SQLCLR用户定义函数来拆分字符串,则有相当好的字符串操作方法。您可以使用以下字符串并为每个搜索项应用string.Format方法。它应该足够快,除非有一个非常高的容量,甚至可能在那时

(\“{0}*\”或FORMSOF(同义词库,{0})或FORMSOF(屈折,{0}))“

我要说的是,可能有更有效的方法来实现这一目标


祝你好运。我希望这能有所帮助。

Ahhh,我忘记了SQL Server中的CLR代码。这实际上看起来是一个非常好的选择,尽管性能有点未知。我们得仔细看一下。。。