C#拼接MySQL日期过滤查询返回早于指定日期数据问题
问题原因
- 核心原因是构造SQL语句时,日期字面量没有加单引号包裹。你当前的写法生成的SQL最终格式类似
SELECT * FROM 表名 where DATE(Date) > 2024-01-01,MySQL会把2024-01-01识别为数值运算表达式(计算结果为2024-1-1=2022),和日期类型字段比较时会触发异常的隐式类型转换,直接导致筛选条件完全失效,因此会返回大量早于阈值的不符合预期的数据。 - 额外存在的问题:直接拼接SQL字符串的写法存在SQL注入风险,无论是表名还是日期参数直接拼接都不安全。
修复方案
优先使用参数化查询修复,既可以解决日期格式/引号问题,也能规避SQL注入风险,表名无法参数化的情况下需要先加白名单校验,修复后代码如下:
public List<OHLC> Select(string table, System.DateTime howFarBack) { // 先做表名白名单校验,避免表名拼接导致的SQL注入 var allowedTables = new HashSet<string> { "你的业务表名1", "你的业务表名2" }; if (!allowedTables.Contains(table)) { throw new ArgumentException("非法的表名参数"); } // SQL语句中用占位符代替直接拼接的参数值 string query = $"SELECT * FROM `{table}` where DATE(Date) > @HowFarBack"; var list = new List<OHLC>(); if (OpenConnection() == true) { MySqlCommand cmd = new MySqlCommand(query, connection); // 添加参数,驱动会自动处理日期类型转换、格式、引号等问题 cmd.Parameters.AddWithValue("@HowFarBack", howFarBack.Date); MySqlDataReader dataReader = cmd.ExecuteReader(); while (dataReader.Read()) { var ohlc = new OHLC(); ohlc.Date = (System.DateTime)dataReader[0]; ohlc.Open = Math.Round((double)dataReader[1], 2); // 原有后续读取逻辑保持不变 } // 补充资源释放逻辑,也可以用using语句自动释放连接、命令、读取器资源 dataReader.Close(); CloseConnection(); } return list; }
如果特殊场景必须手动拼接SQL(非常不推荐),可以临时给日期值加单引号解决筛选失效问题:
// 仅临时应急使用,依然存在SQL注入风险,不推荐长期使用 string query = "SELECT * FROM " + table + " where DATE(Date) > '" + howFarBack.ToString("yyyy-MM-dd") + "'";
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

