从csv字符串搜索sql

时间:2012-02-09 08:40:53

标签: sql sql-server sql-server-2008 tsql

即时搜索页面,我必须使用单个文本框搜索多个字段。 所以我会在我的存储过程中将搜索文本作为CSV字符串

我的表格如下

ID  Name          age   
5   bob           23    
6   bod.harry     34    
7   charles       44    

我需要像这样的SQL查询

declare @searchtext='bob,harry,charley'
select * from employee where  name like (@searchtext) 

此查询应返回此记录(id 5和6)

5 个答案:

答案 0 :(得分:3)

使用(或改编)此拆分功能:

ALTER FUNCTION [dbo].CsvToList(@SplitOn  char(1), @List varchar(8000))
RETURNS TABLE
AS
RETURN 
(
    SELECT
        ROW_NUMBER() OVER(ORDER BY number) AS RowNumber
            ,LTRIM(RTRIM(SUBSTRING(ListValue, number+1, CHARINDEX(@SplitOn, ListValue, number+1)-number - 1))) AS ListValue
        FROM (
                 SELECT @SplitOn + @List + @SplitOn AS ListValue
             ) AS InnerQuery
            INNER JOIN master.dbo.spt_values n ON n.Number < LEN(InnerQuery.ListValue)
        WHERE SUBSTRING(ListValue, number, 1) = @SplitOn
        AND n.type = 'P'
);
GO 

<强>使用

declare @searchtext='bob,harry,charley'
select DISTINCT * from employee e
JOIN dbo.csvToList(',', @searchtext) f
  ON f.ListValue = e.name

答案 1 :(得分:3)

您可以在存储过程中使用这种方式,

declare @searchtext varchar(1000)

set searchtext ='bob,harry,charley'

declare @filter varchar(2000)

set @filter = '(name LIKE ''%' + replace('bob,harry,charley',',','%'' OR name LIKE ''%') + '%'')'

exec
('
    select *
    from mytab
    where ' + @filter + '
'
)

答案 2 :(得分:0)

您需要将@searchtext分成多个字符串,每个字符串一个。它在TSQL中是可行的,但在您的应用程序代码中可能更容易。然后,您可以将它们与您的姓名字段进行比较。

答案 3 :(得分:0)

如果我没弄错,Sql-Server不支持Regex。您可以使用table valued parameters。如果您使用的是实体框架,则可以这样做。

var dc = new MyContext();
var result = dc.employees.Where(x => new [] { "bob", "harry", "charley" }.Contains(x.name));

最后你可以构建以下

select * from employee where  name in (@Param1, @Param2, @Param3, @Param4)

修改

我强烈反对您使用CSV,因为性能下降(您必须解析您的csv)和错误的可能性(考虑这个csv Foo,Bar,"Foo with, comma","comma, "" and quote"

P.S。如果在分配值时使用表值参数,请使用DataTable作为源。

答案 4 :(得分:0)

以上版本的[dbo] .CsvToList不适用于带有大量分隔符的长输入字符串。表spt_values其中type ='P'具有有限的记录数。在我的情况下,函数返回16行而不是66行。有些人建议用数字创建自己的表。我使用了从其他地方复制的这个函数的不同版本:

CREATE FUNCTION [dbo].[fngCsvToList](@SplitOn char(1), @List varchar(8000))
RETURNS @Result TABLE (ListValue varchar(100))
AS
BEGIN 
  DECLARE @str VARCHAR(20) 
  DECLARE @ind Int 
  IF(@List is not null) 
  BEGIN 
    SET @List = REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(@List)), CHAR(10), ''),    CHAR(13), ''), CHAR(9), '')

        SET @ind = CharIndex(@SplitOn, @List) 
        WHILE @ind > 0 
        BEGIN 
              SET @str = SUBSTRING(@List, 1, @ind-1) 
              SET @List = SUBSTRING(@List, @ind+1, LEN(@List)-@ind) 
              INSERT INTO @Result values (LTRIM(RTRIM(@str)))

              SET @ind = CharIndex(',',@List) 
        END 

   SET @str = @List
        INSERT INTO @Result values (LTRIM(RTRIM(@str) ))
  END 
  RETURN 
END