我有一个名为 MyProducts 的表,我想返回 item1 和 item2
SELECT item1, item2 from MyProducts
但是我希望它在我传入的字符串数组(来自 C#)上进行过滤。这是一张非常大的桌子,所以我写了一个“IN”语句。我将如何使用 join 语句来做到这一点。谢谢!
我有一个名为 MyProducts 的表,我想返回 item1 和 item2
SELECT item1, item2 from MyProducts
但是我希望它在我传入的字符串数组(来自 C#)上进行过滤。这是一张非常大的桌子,所以我写了一个“IN”语句。我将如何使用 join 语句来做到这一点。谢谢!
一种解决方案是创建一个临时表并加入它。临时表可以在您将要加入的列上具有索引。
声明没有理由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));
我一直很喜欢这种方法...
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);