我想采用嵌入在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#中执行连接。我认为这是对安全的严重妥协。
答案 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#条件语句。