【问题标题】:Searching for multiple keywords using SQL Server stored procedure使用 SQL Server 存储过程搜索多个关键字
【发布时间】:2012-07-27 08:41:39
【问题描述】:

我将使用存储过程搜索我的数据库 (SQL Server 2008)。我的用户可以在文本框中输入关键字(例如,可以使用 , 分隔关键字)。

目前我正在使用这样的东西:

keyword like N"%'+@SearchQuery%'%"

keyword 是我表中的 nvarchar 列,@SearchQuery 是我的存储过程的输入)

它工作正常,但如果用户输入多个关键字:apple、orange、banana

我应该限制关键字的数量吗?如果我有多个关键字,我应该如何编写存储过程?我应该如何将我的用户输入传递给存储过程?我应该将apple, orange, banana 作为一个完整的短语传递,然后我应该在我的存储过程中解析它们,或者我应该分开我的关键字并发送3个关键字?如何查询这 3 个关键字?一个 for 循环?

执行此类查询的最佳做法是什么?

谢谢

【问题讨论】:

    标签: sql-server-2008 stored-procedures keyword


    【解决方案1】:

    在您的应用程序中解析关键字。 SQL 不是字符串操作的最佳场所。

    将关键字作为表值参数发送(即:http://www.mssqltips.com/sqlservertip/2112/table-value-parameters-in-sql-server-2008-and-net-c/),那么您将不受固定数量的关键字的限制。

    在存储过程的参数中添加通配符

    update @keywords set keyword = '%'+keyword+'%'
    

    通过将源数据加入此表来过滤结果

    例如:

    SELECT result
    FROM source 
        INNER JOIN @keywords keywords 
             ON source.keyword LIKE keywords.keyword
    

    【讨论】:

    • 很好的答案,但这会搜索任何关键字,而不是所有关键字。
    【解决方案2】:

    这取决于: * 你的数据库有多大。 * 用户搜索某事的频率。 * 用户结果如何精确除外。

    LIKE 不是性能守护进程,尤其是从% 开始。

    也许你应该试试full search text

    如果你想留在LIKE(它只适用于小桌子)我会尝试类似:

    1. , 字符分割输入(将它们插入到表中,建议podiluska 是个好主意)。
    2. 为每个令牌和UNION 所有结果构建查询。或者为每个令牌循环运行它并将结果插入临时表。

    如果您需要一些精确的结果(即只有记录匹配所有 3 个单词),您可以从上面构建的临时结果中选择最匹配的结果。

    【讨论】:

    • 我认为 LIKE 是我最好的选择,我认为我应该限制关键字的数量并按照您说的做一些事情,谢谢
    【解决方案3】:

    您可以使用 CTE 将关键字字符串拆分到临时表中,然后根据需要使用它。关键字列表甚至可以有数字或任何字符,如 %$ 或你想要的,只要记住逗号是字符串分隔符

    DECLARE @CommaSeparatorString VARCHAR(MAX),
            @CommaSeparatorXML XML
    DECLARE @handle INT
    SELECT @CommaSeparatorString = 'apple,orange,banana'
    SELECT @CommaSeparatorString = REPLACE(REPLACE(@CommaSeparatorString,'<','$^%'),'>','%^$')
    SELECT @CommaSeparatorXML   =   CAST('<ROOT><i>' + REPLACE(@CommaSeparatorString, ',', '</i><i>') + '</i></ROOT>' AS XML) 
    
    SELECT REPLACE(REPLACE(c.value('.', 'VARCHAR(100)'),'$^%','<'),'%^$','>') AS ID
      FROM (SELECT @CommaSeparatorXML AS CommaXML) a
     CROSS APPLY CommaXML.nodes('//i') x(c)
    

    结果:

      ID
    ------
    apple
    orange
    banana
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-03
      • 2019-01-21
      • 1970-01-01
      • 1970-01-01
      • 2021-04-11
      • 2018-08-24
      • 2011-11-17
      • 2013-01-20
      相关资源
      最近更新 更多