【问题标题】:fast search specific column for specific keywords with stored procedure使用存储过程快速搜索特定列以查找特定关键字
【发布时间】:2015-01-08 20:56:48
【问题描述】:

我写了一个存储过程,得到:

  • "SearchKeys" - 用 ',' "key1,key2" 分隔的搜索键
  • "ToSearch" - 要搜索的表用 ',' 分隔,':' 后面的列用 '.' 分隔"table1:column1.column2,table2:column1.column2"

最后,如果找到了键,过程会返回带有表名和行 ID 的表。

代码如下:

--Search keys in tables
CREATE PROCEDURE [dbo].[Search_All]
(
    @SearchKeys nvarchar(50), --Keys to search separated by ','
    @ToSearch varchar(200) --Tables to search in separated by ',' with colums after ':' separated by '.'
)
AS
BEGIN
    --create table with found values
    CREATE TABLE #Results (TargetId int, DBName varchar(20))

    --Split SearchKeys to Keys
    WHILE LEN(@SearchKeys) > 0
     BEGIN
        DECLARE @Key NVARCHAR(25)
        IF CHARINDEX(',',@SearchKeys) > 0
            SET  @Key = SUBSTRING(@SearchKeys,0,CHARINDEX(',',@SearchKeys))
        ELSE
            BEGIN
            SET  @Key = @SearchKeys
            SET @SearchKeys = ''
        END
        --Split ToSearch to Tables
        WHILE LEN(@ToSearch) > 0
         BEGIN
            DECLARE @TableAndColums VARCHAR(200)
            IF CHARINDEX(',',@ToSearch) > 0
                SET  @TableAndColums = SUBSTRING(@ToSearch,0,CHARINDEX(',',@ToSearch))
            ELSE
                BEGIN
                SET  @TableAndColums = @ToSearch
                SET @ToSearch = ''
                END
            SET @ToSearch = REPLACE(@ToSearch,@TableAndColums + ',' , '')
            --Split @TableAndColums to Table and Colums
            --Select Table
            DECLARE @Table VARCHAR(25)
            SET  @Table = SUBSTRING(@TableAndColums,0,CHARINDEX(':',@TableAndColums))
            SET @TableAndColums = REPLACE(@TableAndColums,@Table + ':' , '')
            --Split to Colums
            WHILE LEN(@TableAndColums) > 0
             BEGIN
                DECLARE @Column VARCHAR(25)
                IF CHARINDEX('.',@TableAndColums) > 0
                    SET  @Column = SUBSTRING(@TableAndColums,0,CHARINDEX('.',@TableAndColums))
                ELSE
                    BEGIN
                    SET  @Column = @TableAndColums
                    SET @TableAndColums = ''
                    END

                    BEGIN
                --insert result in to #Results table
                INSERT INTO #Results
                EXEC
                    (
                        'SELECT ' + @Table + '.Id AS ''TargetId'', '''+@Table+''' AS ''DBName''
                        FROM ' + @Table +
                        ' WHERE  ' + @Column + ' LIKE N''%' + @Key + '%'''
                    )
                END

             SET @TableAndColums = REPLACE(@TableAndColums,@Column + '.' , '')
            END
         END
     SET @SearchKeys = REPLACE(@SearchKeys,@Key + ',' , '')
    END
    --return found values
    SELECT DISTINCT TargetId , DBname FROM #Results
END

由于某种原因,它只搜索第一个键而忽略所有其余键。我不知道为什么会这样。请帮忙!

【问题讨论】:

    标签: sql sql-server search stored-procedures search-engine


    【解决方案1】:

    在这里我要警告您的第一件事是您的程序很容易受到注入攻击。注入攻击本身就是一个广泛的话题。如果你有兴趣,我建议阅读这篇文章。如果你确实需要这种类型的接口(即你不能使用静态类型的 SQL 或类似实体框架的东西来处理你的查询),你必须确保在运行时执行任何字符串(例如@column, @table, @key) 被参数化或括起来。当输入的表不包含 ID 列或输入的列不存在时,此过程也会失败。

    http://www.sommarskog.se/dynamic_sql.html

    关于你如何进行字符串拆分,我会看下面的文章。虽然没有办法消除遍历每个表的需要,但通过使用本文中提到的字符串分割功能将所有搜索字符串放入一个表中,您可以一次搜索单个表上的所有搜索条件。像这样的:

    select *
    from #SearchConditions a
    inner join dbo.TargetTable b
        on b.Name like '%' + a.SearchKey + '%'
    

    http://www.sqlservercentral.com/articles/Tally+Table/72993/

    【讨论】:

      猜你喜欢
      • 2015-04-12
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多