如何根据参数的动态数量过滤查询
How to filter a query based on dynamic number of parameters
如何处理基于用户 selections 的查询中的参数组合。
例如:
public DataTable GetStudents(int fromYear,int toYear,int camp_code,int fac_code,int dep_code)
{
StringBuilder cmdTxt = new StringBuilder();
cmdTxt.Append(" SELECT register_no,name ");
cmdTxt.Append(" FROM student WHERE year BETWEEN ? AND ? ");
cmdTxt.Append(" AND camp_code = ? AND fac_code = ? AND dep_code =? ");//Is a variable
using (var myIfxCmd = new IfxCommand(cmdTxt.ToString(), con))
{
myIfxCmd.CommandType = CommandType.Text;
myIfxCmd.Parameters.Add("year1", IfxType.Integer);
myIfxCmd.Parameters.Add("year2", IfxType.Integer);
if (con.State == ConnectionState.Closed)
{
con.Open();
}
myIfxCmd.Parameters[0].Value = fromYear;
myIfxCmd.Parameters[1].Value = toYear;
//..............
}
- 组织包含一组营地。
- 营地包含一组院系。
- 学院包含一组部门。
在这段代码中我想控制(int camp,int fac,int dep)
。
如果用户select所有阵营那么camp = 0
=>整个组织,所以我想忽略
" AND camp_code = ? AND fac_code = ? AND dep_code =? "
在这种情况下,我只有两个参数 fromYear,toYear
如果用户 select 是一个特定的 camp <> 0
并且想要 select 所有院系然后 fac_code = 0
=> 所有院系,所以我想忽略:
" AND fac_code = ? AND dep_code =? "
在这种情况下,我只有 fromYear,toYear,camp_code
的三个参数
如果用户 select 是一个特定的 camp <> 0
并且 select 是一个特定的教员然后想要 select 该教员下的所有部门然后 dep_code = 0
= > 所有部门,所以我想忽略:
" AND dep_code =? "
在这种情况下,我只有四个参数 fromYear,toYear,camp_code,fac_code
如果用户 select 所有三个参数 <> 0 那么我们将包括所有具有 5 个参数的东西。
我想让它变得动态和灵活以满足这些标准。我解决了它,但被几十个 (IF-ELSE)
语句淹没了。
一如既往,将其分解成更小的部分会让生活更轻松。不要写太多的方法,把它分解成更小的部分。
作为奖励,如果您使用扩展方法,您甚至可以获得流畅的语法,但这并不是真正必要的:
static IfxCommand GetStudents() { //create unfiltered query here ... }
static IfxCommand FilterByYears(
this IfxCommand command,
DateTime start,
DateTime end) { ... }
static IfxCommand FilterByCampus(
this IfxCommand command,
int campusId) { ... }
//etc.
现在,在每个 FilterBy...
方法中,您相应地(或不)修改命令并将其传递。没有意大利面条代码,每个方法只处理一个过滤器。
并且您可以轻松构建查询:
var command =
GetStudents().FilterByYears(start, end)
.FiltersByCampus(campus)
.FilerByFaculty(fac);
您希望您的 SQL 看起来像这样:
cmdTxt.Append(" SELECT register_no,name ");
cmdTxt.Append(" FROM student WHERE year BETWEEN ? AND ? ");
cmdTxt.Append(" AND (camp_code = ? OR camp_code = 0) AND (fac_code = ? or fac_code = 0) AND (dep_code = ? or dep_code = 0) ");
上面的意思就是如果camp_code是0,dep_code是0,fac_code是0,那么都是return。如果camp_code <> 0,且dep_code和fac_code为0,则return特定阵营等
我会做类似于 kowie le roux 建议的事情,只是我相信 参数 为零,而不是数据库中的值。因此,如果您使用 yoda 表示法和 "in" 子句,我认为如果指定字段匹配或提供零值,您可以使 where 条件为真:
select register_no, name
from student
where
year between ? and ? and
? in (camp_code, 0) and
? in (fac_code, 0) and
? in (dep_code, 0)
您需要声明并分配所有五个参数。
此外,就其价值而言,我不知道 Ifx 是什么 -- Informix?如果是这样,请查看它是否支持命名参数。如果是这样,这样的事情有助于使代码更易于维护。
string sql = @"
select register_no, name
from student
where
year between @FROM and @THRU and
@CAMP in (camp_code, 0) and
@FAC in (fac_code, 0) and
@DEP in (dep_code, 0)
";
using (var myIfxCmd = new IfxCommand(sql, con))
{
myIfxCmd.CommandType = System.Data.CommandType.Text;
myIfxCmd.Parameters.Add("@FROM", IfxType.Integer);
myIfxCmd.Parameters.Add("@THRU", IfxType.Integer);
myIfxCmd.Parameters.Add("@CAMP", IfxType.Integer);
myIfxCmd.Parameters.Add("@FAC", IfxType.Integer);
myIfxCmd.Parameters.Add("@DEP", IfxType.Integer);
作业从那里看起来是一样的。
如何处理基于用户 selections 的查询中的参数组合。
例如:
public DataTable GetStudents(int fromYear,int toYear,int camp_code,int fac_code,int dep_code)
{
StringBuilder cmdTxt = new StringBuilder();
cmdTxt.Append(" SELECT register_no,name ");
cmdTxt.Append(" FROM student WHERE year BETWEEN ? AND ? ");
cmdTxt.Append(" AND camp_code = ? AND fac_code = ? AND dep_code =? ");//Is a variable
using (var myIfxCmd = new IfxCommand(cmdTxt.ToString(), con))
{
myIfxCmd.CommandType = CommandType.Text;
myIfxCmd.Parameters.Add("year1", IfxType.Integer);
myIfxCmd.Parameters.Add("year2", IfxType.Integer);
if (con.State == ConnectionState.Closed)
{
con.Open();
}
myIfxCmd.Parameters[0].Value = fromYear;
myIfxCmd.Parameters[1].Value = toYear;
//..............
}
- 组织包含一组营地。
- 营地包含一组院系。
- 学院包含一组部门。
在这段代码中我想控制(int camp,int fac,int dep)
。
如果用户select所有阵营那么camp = 0
=>整个组织,所以我想忽略
" AND camp_code = ? AND fac_code = ? AND dep_code =? "
在这种情况下,我只有两个参数 fromYear,toYear
如果用户 select 是一个特定的 camp <> 0
并且想要 select 所有院系然后 fac_code = 0
=> 所有院系,所以我想忽略:
" AND fac_code = ? AND dep_code =? "
在这种情况下,我只有 fromYear,toYear,camp_code
如果用户 select 是一个特定的 camp <> 0
并且 select 是一个特定的教员然后想要 select 该教员下的所有部门然后 dep_code = 0
= > 所有部门,所以我想忽略:
" AND dep_code =? "
在这种情况下,我只有四个参数 fromYear,toYear,camp_code,fac_code
如果用户 select 所有三个参数 <> 0 那么我们将包括所有具有 5 个参数的东西。
我想让它变得动态和灵活以满足这些标准。我解决了它,但被几十个 (IF-ELSE)
语句淹没了。
一如既往,将其分解成更小的部分会让生活更轻松。不要写太多的方法,把它分解成更小的部分。
作为奖励,如果您使用扩展方法,您甚至可以获得流畅的语法,但这并不是真正必要的:
static IfxCommand GetStudents() { //create unfiltered query here ... }
static IfxCommand FilterByYears(
this IfxCommand command,
DateTime start,
DateTime end) { ... }
static IfxCommand FilterByCampus(
this IfxCommand command,
int campusId) { ... }
//etc.
现在,在每个 FilterBy...
方法中,您相应地(或不)修改命令并将其传递。没有意大利面条代码,每个方法只处理一个过滤器。
并且您可以轻松构建查询:
var command =
GetStudents().FilterByYears(start, end)
.FiltersByCampus(campus)
.FilerByFaculty(fac);
您希望您的 SQL 看起来像这样:
cmdTxt.Append(" SELECT register_no,name ");
cmdTxt.Append(" FROM student WHERE year BETWEEN ? AND ? ");
cmdTxt.Append(" AND (camp_code = ? OR camp_code = 0) AND (fac_code = ? or fac_code = 0) AND (dep_code = ? or dep_code = 0) ");
上面的意思就是如果camp_code是0,dep_code是0,fac_code是0,那么都是return。如果camp_code <> 0,且dep_code和fac_code为0,则return特定阵营等
我会做类似于 kowie le roux 建议的事情,只是我相信 参数 为零,而不是数据库中的值。因此,如果您使用 yoda 表示法和 "in" 子句,我认为如果指定字段匹配或提供零值,您可以使 where 条件为真:
select register_no, name
from student
where
year between ? and ? and
? in (camp_code, 0) and
? in (fac_code, 0) and
? in (dep_code, 0)
您需要声明并分配所有五个参数。
此外,就其价值而言,我不知道 Ifx 是什么 -- Informix?如果是这样,请查看它是否支持命名参数。如果是这样,这样的事情有助于使代码更易于维护。
string sql = @"
select register_no, name
from student
where
year between @FROM and @THRU and
@CAMP in (camp_code, 0) and
@FAC in (fac_code, 0) and
@DEP in (dep_code, 0)
";
using (var myIfxCmd = new IfxCommand(sql, con))
{
myIfxCmd.CommandType = System.Data.CommandType.Text;
myIfxCmd.Parameters.Add("@FROM", IfxType.Integer);
myIfxCmd.Parameters.Add("@THRU", IfxType.Integer);
myIfxCmd.Parameters.Add("@CAMP", IfxType.Integer);
myIfxCmd.Parameters.Add("@FAC", IfxType.Integer);
myIfxCmd.Parameters.Add("@DEP", IfxType.Integer);
作业从那里看起来是一样的。