2012-06-29 58 views
0

我想要检索某个列包含在字符串参数中传递的所有单词的所有行,无论它们出现的顺序如何。返回包含字符串中所有单词的行

如果参数是'hi abc'那么我想该行:abc def hijk,而不是hijk lmnop qr

我设法做到这一点,但我怀疑这是不是很好,所以我想看到的替代品。如何更好地完成我的代码如下?

create table t (s varchar(200)); 
insert into t (s) values 
('abc def hijk'), 
('hijk lmnop qr'), 
('stu'), 
('v xyz') 
; 

create function dbo.matchRows (@string varchar(max)) 
returns varchar(max) 
begin 

    set @string = replace(@string, '''', ''''''); 
    set @string = replace(@string, ' ', ' '); 
    set @string = replace(@string, ' ', ' '); 
    set @string = replace(@string, ' ', '%'' and s like ''%'); 
    set @string = 's like ''%' + @string + '%'''; 
    set @string = 'select * from t where ' + @string; 
    return @string; 

end; 

declare @query varchar(max); 
set @query = (select dbo.matchRows('hi abc')); 
execute (@query); 

回答

4

这样的事情应该工作。它将您的搜索参数转换为XML,然后将其分解为表变量。之后,它会在您的@t表中搜索您传入的所有拆分参数(其中找到的单词的数量等于搜索参数的数量使其与所有这些参数匹配)。

DECLARE @SearchStringParams varchar(max), 
    @Split char(1), 
    @Xml xml, 
    @NumOfSearchTerms Int 
DECLARE @SplitTable table (valToSearchFor varchar(100)); 

SELECT @SearchStringParams = 'hi,abc', 
@Split = ',' 

SELECT @Xml = CONVERT(xml,'<root><s>' + REPLACE(@SearchStringParams,@Split,'</s><s>') + '</s></root>') 

INSERT @SplitTable 
SELECT [Value] = T.c.value('.','varchar(20)') 
FROM @Xml.nodes('/root/s') T(c) 

SELECT @NumOfSearchTerms = @@ROWCOUNT 

DECLARE @t table (searchWords varchar(200)); 
insert into @t (searchWords) values 
('abc def hijk'), 
('hijk lmnop qr'), 
('stu'), 
('v xyz') 
; 
select t.searchWords 
from @t t inner join @SplitTable s 
on t.searchWords like ('%' + s.valToSearchFor + '%') 
group by t.searchWords 
having count(t.searchWords) = @NumOfSearchTerms 
+0

+1需要谨慎的努力。但我想我不会接受它作为“内部连接”,后面跟着“组合”,这比我的简单查询更好或更简洁,在性能方面可能更差。这并不是说处理XML,IMO就像字符串连接一样混乱。 –

+0

在XML上达成一致。另一种方式是如果你使用的是SQL 2008和.net(3.5我认为)将是一个存储过程并传递一个表参数而不是一个字符串。如果你能做到这一点,你可以从最后的选择语句开始。我之前没有与之混淆过,但它不应该太糟糕。 – CompuChip

相关问题