2014-11-06 48 views
0

我的用户试图通过提供简单的文本字符串这样找到我的SQL数据库记录:SQL搜索以任意顺序

SCRAP 000000152 TMB-0000000025

这些值可以是任何顺序和任何可能排除。例如,他们可能会进入:

SCRAP TMB-0000000025 SCRAP 000000152 SCRAP SCRAP 000000152 TMB-0000000025 000000152

所有应该工作,包括相同的记录作为原本的搜索,但他们可能还包含其他记录,因为更少的列中使用比赛。

下面是使用结果的示例表:

DECLARE @search1 varchar(50) = 'SCRAP 000000152 TMB-0000000025' 
DECLARE @search2 varchar(50) = 'SCRAP' 
DECLARE @search3 varchar(50) = 'TMB-0000000025 SCRAP' 
DECLARE @search4 varchar(50) = '000000152 SCRAP' 
DECLARE @search5 varchar(50) = 'SCRAP 000000152' 
DECLARE @search6 varchar(50) = 'TMB-0000000025 000000152' 

DECLARE @table TABLE (WC varchar(20),WO varchar(20),PN varchar(20)) 
INSERT INTO @table 
SELECT 'SCRAP','000000152','TMB-0000000025' UNION 
SELECT 'SCRAP','000','121-0000121515' UNION 
SELECT 'SM01','000000152','121-0000155' UNION 
SELECT 'TH01','00','TMB-0000000025' 

SELECT * FROM @table 

一个额外的皱纹,用户不必进入000000152,他们可以进入152,它应该发现相同的结果。

我可以使用patindex,但它需要用户按照特定的顺序输入搜索词,或者对于我来说,有一个指数级更大的字符串来比较,因为我尝试将它们放入所有可能的排列中。

在SQL中执行此操作的最佳方法是什么?或者,这是否超出了SQL的功能?该表很可能拥有超过10,000条记录(对于某些情况甚至超过100,000条记录),因此查询必须高效。

+0

使用lucene ..... – 2014-11-06 23:54:31

+0

@MitchWheat,你是说在SQL中没有好的方法吗? – davids 2014-11-06 23:56:14

+2

我在说,解决你的问题的最好方法是使用Lucene。你的问题指出:“做这件事的最好方法是什么?” – 2014-11-06 23:56:43

回答

1

同意@MitchWheat(照常)。这个数据库不是为这样的查询而设计的,任何种类的“基本查询”都不会有帮助。最好的方法是创建出现在数据库的任何列中的字符串列表,映射回源列和行,然后在查找表中搜索字符串。这几乎是Lucene和任何其他全文搜索库会为你做的。 SQL有一个本地实现,但如果专业人士说与第三方实现,我会说这是值得一看。

0

你可以试试这个SP:

USE master 
GO 

CREATE PROCEDURE sp_FindStringInTable @stringToFind VARCHAR(100), @schema sysname, @table sysname 
AS 

DECLARE @sqlCommand VARCHAR(8000) 
DECLARE @where VARCHAR(8000) 
DECLARE @columnName sysname 
DECLARE @cursor VARCHAR(8000) 

BEGIN TRY 
    SET @sqlCommand = 'SELECT * FROM [' + @schema + '].[' + @table + '] WHERE' 
    SET @where = '' 

    SET @cursor = 'DECLARE col_cursor CURSOR FOR SELECT COLUMN_NAME 
    FROM ' + DB_NAME() + '.INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_SCHEMA = ''' + @schema + ''' 
    AND TABLE_NAME = ''' + @table + ''' 
    AND DATA_TYPE IN (''char'',''nchar'',''ntext'',''nvarchar'',''text'',''varchar'')' 

    EXEC (@cursor) 

    OPEN col_cursor  
    FETCH NEXT FROM col_cursor INTO @columnName  

    WHILE @@FETCH_STATUS = 0  
    BEGIN  
     IF @where <> '' 
      SET @where = @where + ' OR' 

     SET @where = @where + ' [' + @columnName + '] LIKE ''' + @stringToFind + '''' 
     FETCH NEXT FROM col_cursor INTO @columnName  
    END  

    CLOSE col_cursor  
    DEALLOCATE col_cursor 

    SET @sqlCommand = @sqlCommand + @where 
    --PRINT @sqlCommand 
    EXEC (@sqlCommand) 
END TRY 
BEGIN CATCH 
    PRINT 'There was an error. Check to make sure object exists.' 
    IF CURSOR_STATUS('variable', 'col_cursor') <> -3 
    BEGIN 
     CLOSE col_cursor  
     DEALLOCATE col_cursor 
    END 
END CATCH 

这将有结果如下:

USE AdventureWorks 
GO 
EXEC sp_FindStringInTable 'Irv%', 'Person', 'Address' 

enter image description here

USE AdventureWorks 
GO 
EXEC sp_FindStringInTable '%land%', 'Person', 'Address' 

enter image description here 这一切就是这么简单。一旦创建完成,你可以在服务器上的任何表和任何数据库上使用它。(Read More

+0

这是一种在任何字段中查找单个字符串(或部分字符串)的方法,但我需要找到一个记录,该记录在几个字段中具有几个分支的匹配项。它可能适合我的需要,但我怀疑它将远没有效率。 – davids 2014-11-07 15:02:57