我有一个名为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语句之前变老。
如果您分享了检索符合所选搜索条件的数据的练习,如果您有许多选项可以选择,我将不胜感激。
谢谢!
答案 0 :(得分:5)
如果您必须将emergency_type用作字符串,那么您可以发送包含紧急类型的文本表示的List,而不是传入bool。例如,要调整上面的代码,您可以将方法签名更改为
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'"
创建values变量的一种简单方法是使用
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
答案 1 :(得分: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 += ")";
答案 2 :(得分:0)
应该避免字符串连接,因为它可能导致一些讨厌的漏洞。 如果您正在寻找程序访问方面的最佳实践,那么此处的最佳做法是使用参数化查询。
如果你想要便宜,那么让in子句获取一个参数,并从选中的复选框列表中将该字符串连接在一起,并将其作为in子句的参数值传递。它看起来像这样:
where ... and emergency_type in (?)
另一种方法是计算检查的复选框的数量,并为in子句构建参数列表,使其看起来更像这样:
where ... and emergency_type in(?,?...) -- as many params as there are checked checkboxes.
其中任何一个都可以。 使用这些类型的查询,我已经建立了自己的SQL构造函数方法,我保留了内部计数参数及其数据类型,并动态构建了sql,然后使用已知的良好参数列表进行准备
你可以看看学习Linq。
答案 3 :(得分:0)
构建用户的比较值列表(@EmergencyList),并使用包含运算符的参数化查询使用SQL。
SELECT call_time,
location,
emergency_type
where call_time between @from AND @to
AND CONTAINS( Emegency_Type, @EmergencyList )