SQL Server SELECT语句过滤字符串数组

时间:2012-10-05 12:55:42

标签: c# sql-server arrays

我有一个名为MyProducts的表,我想返回item1和item2

SELECT item1, item2 from MyProducts

但是我希望它在我传入的字符串数组(来自C#)上进行过滤。这是一张非常大的表,所以我的'IN'声明已经出来了。我如何使用join语句执行此操作。谢谢!

3 个答案:

答案 0 :(得分:1)

一种解决方案是创建一个临时表并与之连接。临时表可以在您要加入的列上有索引。

答案 1 :(得分:1)

IN陈述没有理由“出局”;最终,这是一种非常合理的过滤方式 - 让优化器担心各种选项。它当然不受MyProducts大的事实的影响。添加连接会带来更多工作:但是,它不会减少“命中”的数量或涉及的工作量。例如,用dapper做到这一点就是:

string[] filter = ...
var rows = connection.Query(
     "select item1, item2 from MyProducts where SomeField in @filter",
     new {filter});

或使用LINQ:

string[] filter = ...
var rows = db.Products.Where(x => filter.Contains(x.SomeField));

答案 2 :(得分:1)

我一直很喜欢这种方法......

CREATE FUNCTION dbo.Split(@String varchar(max), @Delimiter char(1))        
returns @temptable TABLE (Value varchar(max))        
as        
begin        
    declare @idx int        
    declare @slice varchar(max)        

        select @idx = 1        
        if len(@String)<1 or @String is null  return        

    while @idx!= 0        
    begin        
        set @idx = charindex(@Delimiter,@String)        
        if @idx!=0        
            set @slice = left(@String,@idx - 1)        
        else        
            set @slice = @String        

        if(len(@slice)>0)   
            insert into @temptable(Items) values(@slice)        

        set @String = right(@String,len(@String) - @idx)        
        if len(@String) = 0 break        
    end    
return        
end 

然后你可以这样做......

CREATE PROCEDURE MySp
    @list varchar(max)
AS 

SELECT <columns> 
  FROM <mytable> mt
 INNER JOIN dbo.split(@list,',') s ON s.Value= my.Key

注意:有许多分割功能,所以你不必使用这个特定功能。


我在使用SQL Server 2008时使用的另一种方法是使用像这样的表参数...

CREATE TYPE [dbo].[LookupTable] As Table
(
    ID Int primary key
)

CREATE PROCEDURE [dbo].[SampleProcedure]
(
    @idTable As [dbo].[LookupTable] Readonly
)
AS
BEGIN
    SELECT <columns> 
      FROM <mytable> mt
     INNER JOIN @idTable s ON s.Id= my.Key
END

以这种方式将参数从C#传递到SQL Server ......

DataTable dataTable = new DataTable("SampleDataType"); 
dataTable.Columns.Add("Id", typeof(Int32)); 
foreach (var id in <mycollectionofids>)
    dataTable.Rows.Add(id); 

SqlParameter parameter = new SqlParameter(); 
parameter.ParameterName="@Id"; 
parameter.SqlDbType = System.Data.SqlDbType.Structured; 
parameter.Value = dataTable; 
command.Parameters.Add(parameter);