我的用户正在尝试通过提供如下所示的简单文本字符串来查找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','000012312','121-0000121515' UNION
SELECT 'SM01','000000152','121-0000155' UNION
SELECT 'TH01','000123151','TMB-0000000025'
SELECT * FROM @table
一个额外的皱纹,用户无需输入000000152
,他们可以输入152
,它应该会找到相同的结果。
我可以使用patindex,但它要求用户按特定顺序输入搜索字词,或者让我有一个指数级较大的字符串进行比较,因为我尝试将它们置于所有可能的安排中。
在SQL中执行此操作的最佳方法是什么?或者,这是否超出SQL的能力?该表很可能有超过10,000条记录(有些情况甚至超过100,000条记录),因此查询必须高效。
答案 0 :(得分:1)
同意@MitchWheat(照例)。此数据库不是为这样的查询而设计的,也不是任何类型的基本查询"救命。最好的方法是构建一个出现在数据库任何列中的字符串列表,映射回源列和行,并在该查找表中搜索字符串。这几乎是Lucene和任何其他全文搜索库将为您做的事情。 SQL有一个本地实现,但如果专业人士说与第三方实现一起使用,我说它值得一看。
答案 1 :(得分: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'
USE AdventureWorks
GO
EXEC sp_FindStringInTable '%land%', 'Person', 'Address'
这就是它的全部内容。创建完成后,您可以对服务器上的任何表和任何数据库使用此功能。(Read More)