Java 8与MySQL:CASE语句中变量日期的正确格式化方法
问题:MySQL CASE语句中对比Java变量日期异常
原可正常运行的CASE语句(使用NOW()做对比):
CASE WHEN (DATE_ADD(dob, INTERVAL 10 YEAR) < NOW()) THEN 'M3' WHEN (DATE_ADD(dob, INTERVAL 9 YEAR) < NOW()) THEN 'M2' WHEN (DATE_ADD(dob, INTERVAL 8 YEAR) < NOW()) THEN 'M1' WHEN (DATE_ADD(dob, INTERVAL 7 YEAR) < NOW()) THEN 'U' ELSE 'LS' END AS milestoneBracket
需要将NOW()替换为Java生成的格式化日期(如2022-07-17),但几次尝试均失败:
WHEN (DATE_ADD(dob, INTERVAL 10 YEAR) < df1.format(date)) THEN 'M3':始终返回'LS'WHEN (DATE_ADD(dob, INTERVAL 10 YEAR) < 'df1.format(date)') THEN 'M3':始终返回'M3'WHEN (DATE_ADD(dob, INTERVAL 10 YEAR) < 'df1.format(date)->format('Y-m-d')') THEN 'M3':直接报错
解决方案
方式一:使用JDBC参数化查询(推荐)
不要直接拼接字符串,用JDBC的PreparedStatement传递日期参数,MySQL会自动处理日期类型匹配,同时避免SQL注入风险:
Java代码示例:
String sql = "SELECT " + "CASE " + " WHEN (DATE_ADD(dob, INTERVAL 10 YEAR) < ?) THEN 'M3' " + " WHEN (DATE_ADD(dob, INTERVAL 9 YEAR) < ?) THEN 'M2' " + " WHEN (DATE_ADD(dob, INTERVAL 8 YEAR) < ?) THEN 'M1' " + " WHEN (DATE_ADD(dob, INTERVAL 7 YEAR) < ?) THEN 'U' " + "ELSE 'LS' " + "END AS milestoneBracket " + "FROM your_table"; PreparedStatement pstmt = connection.prepareStatement(sql); // 假设date是Java的Date类型,转换为sql.Date传入 java.sql.Date sqlDate = new java.sql.Date(date.getTime()); pstmt.setDate(1, sqlDate); pstmt.setDate(2, sqlDate); pstmt.setDate(3, sqlDate); pstmt.setDate(4, sqlDate); ResultSet rs = pstmt.executeQuery();
方式二:正确拼接格式化后的日期字符串
如果必须拼接SQL字符串,需确保Java生成的日期字符串被正确嵌入,且MySQL能识别为日期类型:
Java代码示例:
// 先将Java日期格式化为MySQL支持的'yyyy-MM-dd'格式字符串 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); String targetDate = df.format(date); // 拼接SQL时,用单引号包裹日期字符串 String sql = "SELECT " + "CASE " + " WHEN (DATE_ADD(dob, INTERVAL 10 YEAR) < '" + targetDate + "') THEN 'M3' " + " WHEN (DATE_ADD(dob, INTERVAL 9 YEAR) < '" + targetDate + "') THEN 'M2' " + " WHEN (DATE_ADD(dob, INTERVAL 8 YEAR) < '" + targetDate + "') THEN 'M1' " + " WHEN (DATE_ADD(dob, INTERVAL 7 YEAR) < '" + targetDate + "') THEN 'U' " + "ELSE 'LS' " + "END AS milestoneBracket " + "FROM your_table";
之前尝试失败的原因:
- 第一种写法中
df1.format(date)未被Java解析执行,直接作为无效字符串传入MySQL,导致日期对比始终为假,返回LS。 - 第二种写法把
df1.format(date)当成固定字符串,MySQL按字符串规则对比而非日期规则,导致结果异常。 - 第三种写法存在字符串嵌套语法错误,直接触发SQL语法报错。
内容的提问来源于stack exchange,提问作者Glyn
相关产品推荐
相关产品推荐

