“动态 SQL 报语法错”是一个很常见但原因很多的问题。下面按最常见原因 → 排查思路 → 示例来说明。
这是最容易犯的错误。
❌ 错误示例(MyBatis):
<select id="test">
select * from user
<if test="name != null">
where name = #{name}
</if>
</select>
如果 name == null,SQL 会变成:
select * from user
✅ 没问题
但如果是:
select * from user
<if test="name != null">where name = #{name}</if>
<if test="age != null">and age = #{age}</if>
当 name == null 时:
select * from userand age = ?
→ 语法错误
✅ 正确写法:
where 1=1
<if test="name != null">and name = #{name}</if>
<if test="age != null">and age = #{age}</if>
或用 <where> 标签。
${} 但拼接内容非法${} 是原样拼接 SQL,非常容易出错。
❌ 错误:
order by ${sortField} ${sortType}
如果 sortType = "desc;" 或 sortType = ""
→ SQL 语法错误
✅ 建议:
if (!"asc".equals(sortType) && !"desc".equals(sortType)) {
throw new IllegalArgumentException();
}
❌ 错误(手写 SQL):
where name = ${name}
如果 name = Tom → SQL 变成:
where name = Tom
✅ 应改为:
where name = #{name}
常见错误:
<if> 里写 SQL 片段不完整<foreach> 拼接 IN 为空❌ 错误:
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
如果 ids 为空:
in ()
→ 语法错误
✅ 处理:
<if test="ids != null and ids.size() > 0">
and id in
<foreach ... >
</if>
例如:
limitlimitlimit 可用但语法不同✅ 动态 SQL 要区分数据库
打印最终 SQL
logImpl=STDOUT_LOGGINGshow-sql=true看报错位置
You have an error in your SQL syntax near '...'
看 near 后面是什么
复制到数据库客户端执行 最容易定位问题
你可以贴出:
我可以直接告诉你哪一行导致语法错误,以及怎么改。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。