SQL Server:连接WHERE子句。寻求合适的模式

时间:2009-10-09 13:14:13

标签: sql-server stored-procedures select concatenation

我想采用嵌入在C#代码中的设计糟糕的SQL语句,并将其重写为存储过程(大概),并且正在寻找适当的方法来解决以下模式:

sql = "SELECT <whatever> FROM <table> WHERE 1=1";

if ( someCodition.HasValue )
{
    sql += " AND <some-field> = " + someCondition.Value;
}

这是一种简化。实际的陈述很长,包含几个这样的条件,如果条件存在,其中一些条件包括INNER JOIN到其他表。最后一部分是关键,否则我可能能够用以下方法解决所有问题:

WHERE <some-condition-value> IS NULL OR <some-field> = <some-condition-value>

我可以想到一些可能的方法。我正在寻找正确的方法。

修改 我不想在C#中执行连接。我认为这是对安全的严重妥协。

3 个答案:

答案 0 :(得分:1)

你可以从

开始
StringBuilder sb = new StringBuilder();
sb.Append("SELECT <whatever> FROM <table> WHERE  1 = 1 ");

if ( someCodition.HasValue )
{
    sb.Append(" AND <some-field> = " + someCondition.Value);
}

// And so on

将省去放置第一个WHERE - AND

的麻烦

[编辑]

你也可以尝试这个

创建一个包含表的所有必需参数的SP,并像这样编写查询。

DECLARE @sqlStatement NVARCHAR(MAX)

 @sqlStatement = " SELECT fields1, fields2 FROM TableA WHERE  1 = 1 "
if(@param1 IS NOT NULL)  @sqlStatement = @sqlStatement + "AND Column1 = " + @param1
if(@param2 IS NOT NULL)  @sqlStatement = @sqlStatement + "AND Column2 = " + @param2
// and so on 

sp_executeSql @sqlStatement

你也可以试试类似的SP但是:

SELECT fields1, fields2 FROM TableA WHERE  1 = 1 
AND ( ( @param1 IS NULL ) OR ( Column1 = @param1 ) )
AND ( ( @param2 IS NULL ) OR ( Column2 = @param2 ) )

这绝对是注射证明!

答案 1 :(得分:1)

从这个WHERE子句开始:

WHERE 1=1

然后将所有条件附加为:

AND <some-field> = " + someCondition.Value;

优化器会抛出1 = 1条件,你不必担心太多的ANDs

编辑基于OP关于不想连词的评论:

这是一篇关于如何处理这个主题的非常全面的文章:

Dynamic Search Conditions in T-SQL by Erland Sommarskog

它涵盖了尝试使用多个可选搜索条件编写查询的所有问题和方法

这是目录:

  Introduction
      The Case Study: Searching Orders
      The Northgale Database
   Dynamic SQL
      Introduction
      Using sp_executesql
      Using the CLR
      Using EXEC()
      When Caching Is Not Really What You Want
   Static SQL
      Introduction
      x = @x OR @x IS NULL
      Using IF statements
      Umachandar's Bag of Tricks
      Using Temp Tables
      x = @x AND @x IS NOT NULL
      Handling Complex Conditions
   Hybrid Solutions – Using both Static and Dynamic SQL
      Using Views
      Using Inline Table Functions
   Conclusion
   Feedback and Acknowledgements
   Revision History

答案 2 :(得分:1)

如果我理解这个问题,那么想法就是用C#替换C#中的整段代码,负责生成“long hand”,一个对应于搜索条件列表的特定SQL语句,通过一次调用存储过程,它将在SQL端使用查询的通用模板,旨在以统一的方式处理所有允许的搜索条件组合。

除了将在应用程序端评估的表达式(例如someCondition.HasValue)映射到SQL端评估的表达式(例如“some-condition-value”)的困难之外,您设想的解决方案可能是<强大的>逻辑上/功能上等同于到“手工制作”的SQL语句,但更慢,更苛刻的SQL资源

基本上,C#代码封装了有关数据库及其架构的“物理”布局的特定知识。它使用此信息来确定何时可能需要特定的JOIN,或者当特定的应用程序级搜索条件值转换为表示SQL“LIKE”而不是“=”预测时。它还可以包含业务规则,例如“当提供邮政编码时,按照而不是按国家搜索”。

您是正确的尝试和解耦数据模型(应用程序看待数据的方式)来自数据模式(它在SQL中声明和存储的方式) ),但需要以某种方式在某处进行正确的映射 在应用程序级别执行此操作,具有C#的所有表现力而不是T-SQL,如果完成,则不一定是坏事   - 在独立于应用程序其他功能的模块中 并且,在可行的情况下,
  - 它有点数据/配置驱动,因为允许通过更改配置文件来实现数据模型中的小变化(比如添加搜索条件),而不是将其插入到长序列中间的某个位置C#条件语句。