如果查询可以依赖于许多不同的列,那么就没有好的单条 T-SQL 语句来处理它。要获得像体面的执行计划这样的东西,您需要针对您想要的确切组合的 T-SQL。执行此操作的方法是动态构建 SQL。
现在您有 3 个选项:
- 在存储过程中生成 T-SQL,并用于
sp_ExecuteSQL
执行它(保留正确的参数化和查询计划重用)
- 首先不要使用存储过程:在 C# 中生成 T-SQL 并执行它
- 使用 ORM
第一个选项是可行的,但很痛苦——T-SQL 根本不适合这个。但你可以做到。例如(缩写):
declare @tsql nvarchar(4000) = 'select * from foo ...'
if @name is not null
set @tsql = @sql + ' and Name = @name'
if @region is not null
set @tsql = @sql + ' and Region = @region'
-- ...
exec sp_executesql @tsql,
N'@name nvarchar(50), @region int`,
@name, @region
C# 选项更容易 IMO - 通常通过StringBuilder
- 只需添加您需要的子句和参数。
最后,使用 ORM(在本例中为 LINQ 提供程序):
IQueryable<Foo> foos = ctx.Foos;
if(name != null) foos = foos.Where(x => x.Name == name);
if(region != null) foos = foos.Where(x => x.Region == region);
// ...