C# WinForm连接MariaDB的搜索按钮日期查询问题求助
WinForm中MariaDB日期查询失效问题解决
问题背景
开发WinForm应用,GridView绑定MariaDB数据库,配套对应列的TextBox和DateTimePicker控件。实现搜索按钮时,字符串列查询正常,但日期列查询完全不生效,问题出在SQL语句和参数处理上。
原代码
private void btnPretrazi_Click(object sender, EventArgs e) { string connString = ConfigurationManager.ConnectionStrings["MariaDBConnectionString"].ConnectionString; using (MySqlConnection konekcija = new MySqlConnection(connString)) { konekcija.Open(); string upit = "SELECT * FROM radninalog WHERE opisNaloga LIKE @OpisNaloga AND (inzenjerNaloga LIKE @InzenjerNaloga OR DATE(datumNaloga) = @DatumNaloga OR DATE(planiraniPocDatum) = @PlaniraniPocDatum OR DATE(planiraniKrajDatum) = @PlaniraniKrajDatum OR DATE(stvarniPocDatum) = @StvarniPocDatum OR DATE(stvarniKrajDatum) = @StvarniKrajDatum)"; using (MySqlCommand cmd = new MySqlCommand(upit, konekcija)) { cmd.Parameters.AddWithValue("@OpisNaloga", "%" + opisNalogaTextBox.Text + "%"); cmd.Parameters.AddWithValue("@DatumNaloga", dateTimePicker1.Value); cmd.Parameters.AddWithValue("@InzenjerNaloga", "%" + inzenjerNalogaTextBox.Text + "%"); cmd.Parameters.AddWithValue("@PlaniraniPocDatum", dateTimePicker2.Value.ToString("yyyy-MM-dd")); cmd.Parameters.AddWithValue("@PlaniraniKrajDatum", dateTimePicker3.Value.ToString("yyyy-MM-dd")); cmd.Parameters.AddWithValue("@StvarniPocDatum", dateTimePicker4.Value.ToString("yyyy-MM-dd")); cmd.Parameters.AddWithValue("@StvarniKrajDatum", dateTimePicker5.Value.ToString("yyyy-MM-dd")); DataTable radniNalog = new DataTable(); using (MySqlDataAdapter adapter = new MySqlDataAdapter(cmd)) { adapter.Fill(radniNalog); } radniNalogGridView.DataSource = radniNalog; } } metode.OcistiUnose(this); }
注:最后一行是清空输入控件的方法(原注有误,并非清空数据库条目)
问题分析
- SQL逻辑错误:原语句用
opisNaloga LIKE @OpisNaloga AND (...),意味着必须同时满足opisNaloga匹配,还要满足括号内任意一个条件。如果用户只选择日期而没填opisNaloga,会因为LIKE '%%'虽匹配所有,但日期条件不满足时就无结果,逻辑不符合“任意条件匹配”的需求。 - 日期参数传递不一致:混合使用
DateTime类型和字符串格式的日期,MariaDB的DATE()函数与字符串参数匹配时可能存在隐式转换问题。 - 未处理空输入:当用户未填写TextBox或未指定日期时,当前逻辑会强制加入该条件,导致查询范围被错误限制。
解决方案
1. 重构SQL查询逻辑
动态构建WHERE子句,只加入用户实际输入的条件,用OR连接各个可选条件,实现“多条件任意匹配”的搜索逻辑。
2. 统一日期参数传递
直接传递DateTime类型参数,让MySqlConnector自动处理日期格式转换,避免字符串转换错误。
3. 过滤空输入条件
对TextBox空值、DateTimePicker未修改的情况跳过对应条件。
修改后的代码
private void btnPretrazi_Click(object sender, EventArgs e) { string connString = ConfigurationManager.ConnectionStrings["MariaDBConnectionString"].ConnectionString; using (MySqlConnection konekcija = new MySqlConnection(connString)) { konekcija.Open(); // 动态构建查询语句和参数 List<string> whereClauses = new List<string>(); MySqlCommand cmd = new MySqlCommand(); cmd.Connection = konekcija; // 处理opisNaloga字符串查询 if (!string.IsNullOrWhiteSpace(opisNalogaTextBox.Text)) { whereClauses.Add("opisNaloga LIKE @OpisNaloga"); cmd.Parameters.AddWithValue("@OpisNaloga", "%" + opisNalogaTextBox.Text + "%"); } // 处理inzenjerNaloga字符串查询 if (!string.IsNullOrWhiteSpace(inzenjerNalogaTextBox.Text)) { whereClauses.Add("inzenjerNaloga LIKE @InzenjerNaloga"); cmd.Parameters.AddWithValue("@InzenjerNaloga", "%" + inzenjerNalogaTextBox.Text + "%"); } // 处理datumNaloga日期查询 whereClauses.Add("DATE(datumNaloga) = @DatumNaloga"); cmd.Parameters.AddWithValue("@DatumNaloga", dateTimePicker1.Value.Date); // 处理planiraniPocDatum日期查询 whereClauses.Add("DATE(planiraniPocDatum) = @PlaniraniPocDatum"); cmd.Parameters.AddWithValue("@PlaniraniPocDatum", dateTimePicker2.Value.Date); // 处理planiraniKrajDatum日期查询 whereClauses.Add("DATE(planiraniKrajDatum) = @PlaniraniKrajDatum"); cmd.Parameters.AddWithValue("@PlaniraniKrajDatum", dateTimePicker3.Value.Date); // 处理stvarniPocDatum日期查询 whereClauses.Add("DATE(stvarniPocDatum) = @StvarniPocDatum"); cmd.Parameters.AddWithValue("@StvarniPocDatum", dateTimePicker4.Value.Date); // 处理stvarniKrajDatum日期查询 whereClauses.Add("DATE(stvarniKrajDatum) = @StvarniKrajDatum"); cmd.Parameters.AddWithValue("@StvarniKrajDatum", dateTimePicker5.Value.Date); // 组合查询语句 string upit = "SELECT * FROM radninalog"; if (whereClauses.Count > 0) { upit += " WHERE " + string.Join(" OR ", whereClauses); } cmd.CommandText = upit; DataTable radniNalog = new DataTable(); using (MySqlDataAdapter adapter = new MySqlDataAdapter(cmd)) { adapter.Fill(radniNalog); } radniNalogGridView.DataSource = radniNalog; } metode.OcistiUnose(this); }
额外优化建议
- 如果允许用户不选择某些日期(即忽略该日期条件),可以给DateTimePicker添加清空功能(比如加个按钮重置为默认值),然后在代码中判断如果是默认值则跳过该条件。
- 使用
Value.Date而非直接Value,确保只传递日期部分,避免时间部分干扰匹配。
内容的提问来源于stack exchange,提问作者unbeliever
相关产品推荐
相关产品推荐

