2008-11-01 82 views
4

我有一个名为call的数据库表,其中列call_time,location,emergency_type,并且有三种类型的紧急情况:医务人员,警察和消防员。在Windows窗体中,我创建了CheckBoxes的“护理人员”,“警察”,“消防员”,我想检索满足用户选择的所有表格列。检索符合选定条件的数据的最佳做法

我创建了一个功能:

public static DataTable GetHistory(DateTime from, DateTime to, bool paramedics, bool police, bool firefighters) 
    { 
     string select = 
      "SELECT call_time, location, emergency_type where call_time between @from AND @to AND"; 
     if(paramedics) 
     { 
      select += " emergency_type = 'paramedics' "; 
     } 
     if(paramedics && police) 
     { 
      select +=" emergency_type = 'paramedics' OR emergency_type = 'police'; 
     } 
     ... 

    } 

此代码然而看起来非常脏,因为如果有30个各种紧急会有30!在编写所有if语句之前,我会变老。

如果您共享您检索符合所选搜索条件,如果有,你可以chosse很多选择数据的做法我将不胜感激。

谢谢!

+0

顺便说一句,如果语句运行了一个又一个,所以如果医护人员和警察都是真的,你wouold用字符串” ...... emergency_type最终=‘救护’emergency_type =‘救护’OR emergency_type =‘警察’ “ – Ady 2008-11-01 08:58:17

+0

这只是一个方法示例,而不是工作版本。 – 2008-11-01 20:02:22

回答

5

那么如果你必须使用emergency_type作为一个字符串,然后强似在布尔变量,你可以在包含紧急类型的文本表示列表发送。例如,要调整上面的代码,你可以在方法签名更改为

public static DataTable GetHistory(DateTime from, DateTime to, List<string> types) 
{ 
.. 
} 

,然后通过在一个看起来像这些(例如)

List<string> types = 
    new List<string> { "paramedics" }; 

or 

List<string> types = 
    new List<string> { "paramedics", "police" }; 

列表然后你可以调整你的查询中使用where子句中的SQL IN语句。接下来字符串列表转换成一个逗号分隔的字符串喜欢

string values = "'paramedics', 'police'" 

一个简单的方法来创建数值变量是使用

string values = string.Empty; 
      types.ForEach(s => 
      { 
       if (!string.IsNullOrEmpty(values)) 
        values += ","; 
       values += string.Format("'{0}'", s); 

      }); 

顺便说一句,你可以使用参数化的命令,以避免SQL注入。一旦你有字符串,你可以简单地做

string select = 
"SELECT call_time, location, emergency_type where call_time between @from AND @to AND emergency_type IN " + values 
0

这是一个肮脏的做法。

string select = "SELECT call_time, location, emergency_type where call_time between @from AND @to AND (1=0"; 

if(paramedics) { select += " OR emergency_type = 'paramedics' "; } 
if(police)  { select += " OR emergency_type = 'police'"; } 
if(xyz)  { select += " OR emergency_type = 'xyz'"; } 

select += ")"; 
0

应该避免字符串连接,因为它可以导致一些讨厌的漏洞。 如果您正在寻找有关程序化访问的最佳实践,那么此处的最佳做法是使用参数化查询。

如果您想要便宜,请使in子句采用一个参数,并将该字符串连接在一起,并将其作为in子句的参数值传递给checkbox。它应该是这样的:

where ... and emergency_type in (?) 

的另一种方式做到这一点是计算所选中的复选框的数量,并建立参数列表的条款,所以它看起来更像是这样的:

where ... and emergency_type in(?,?...) -- as many params as there are checked checkboxes. 

其中任何一个都可以。 有了这些类型的查询,我已经走了这么远,建立自己的SQL构造方法,我把参数的内部计数,他们的数据类型和动态生成SQL语句,然后执行与良好的已知列表准备参数。

你可能会看看学习Linq。

0

构建用户的比较值列表(@EmergencyList),并使用包含运算符的参数化查询使用SQL。

SELECT call_time, 
     location, 
     emergency_type 
where call_time between @from AND @to 
    AND CONTAINS(Emegency_Type, @EmergencyList)