【发布时间】:2016-07-21 16:26:00
【问题描述】:
我正在尝试使用 join 执行 HQL 删除。经过很快的搜索,我发现我需要创建一个查询,就像这里建议的那样:
http://dasunhegoda.com/1093-you-cant-specify-target-table-table_name-for-update-in-from-clause/104/
这是我的查询:
dao.executeByHql(
"DELETE FROM FinalGradeResult e WHERE e.id IN "
+ "( SELECT id FROM "
+ "( SELECT x FROM FinalGradeResult x "
+ "where x.student.id = :studentId "
+ " AND x.classDiscipline IN " +
+ "(SELECT cd from ClassDiscipline cd "
+ " where cd.clazz.id = :clazzId ) ) as X )",
new HqlParameter("studentId", student.getId()),
new HqlParameter("clazzId", from.getId()));
但我不断收到此错误:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token:( near line 1, column 94 [DELETE FROM xxxxxxxxxxxx.entity.FinalGradeResult e WHERE e.id IN ( SELECT id FROM ( SELECT x FROM xxxxxxxxxxxxxxx.entity.FinalGradeResult x where x.student.id = :studentId AND x.classDiscipline IN (SELECT cd from xxxxxxxxxxxxxxxx.entity.ClassDiscipline cd where cd.clazz.id = :clazzId ) ) as X )]
错误指出第二个(是错误的,"SELECT id FROM"后面的那个
编辑我试过这样,同样的错误发生:
dao.executeByHql(
"DELETE FROM FinalGradeResult e WHERE e.id IN "
+ "( SELECT id FROM "
+ "( SELECT x FROM FinalGradeResult x "
+ " where x.student.id = :studentId "
+ " AND x.classDiscipline.clazz.id = :clazzId )"
+ " as X )",
EDIT 2:由于我在这个问题中发布的链接中描述的问题,这样的查询不起作用:
dao.executeByHql(
"DELETE FROM FinalGradeResult e WHERE e.id IN " + "( SELECT x.id FROM FinalGradeResult as x "
+ " where x.student.id = :studentId " + " AND x.classDiscipline.clazz.id = :clazzId )",
new HqlParameter("studentId", student.getId()), new HqlParameter("clazzId", from.getId()));
错误是:
Caused by: java.sql.SQLException: You can't specify target table 'tb_final_grade_result' for update in FROM clause
解决方案
在尝试了一切之后,我们得出了以下结论:
- 我们不能直接只有一个查询,因为我们不能在 DELETE 上进行连接。
- 我们不能只有 2 个查询(一个子查询),因为我们有一个 MYSQL BUG(在提供的链接中描述)
- 我们不能有 3 个查询(2 个子查询),因为 FROM 子句中不能有子查询。这就是为什么我们的第二个查询不起作用
(select * from (select ...))无效。
所以我决定使用 NativeSQL 来解决问题:
dao.executeBySQL(
" delete from tb_final_grade_result where id in "
+ " (select * from ( select finalgrade1_.id from tb_final_grade_result finalgrade1_ cross join tb_class_discipline classdisci2_ "
+ " where finalgrade1_.id_class_discipline=classdisci2_.id and finalgrade1_.id_student= :studentId and classdisci2_.id_class= :clazzId ) as tmp )",
new HqlParameter("studentId", student.getId()), new HqlParameter("clazzId", from.getId()));
特别感谢@scaisEdge
【问题讨论】:
-
如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做,请提供适当的 DDL(和/或 sqlfiddle),以便我们可以更轻松地复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。
-
谢谢你 StrawBerry。我无法创建 sqlfiddle,因为 HQL 给出了语法错误,甚至没有生成 SQL :(
-
我不明白那个评论。
-
Hibernate 无法执行 HQL,因为 HQL 查询中有“意外令牌”。但我认为查询看起来不错。 @scaisEdge 和考虑我正在尝试帮助我修复它。但是我还是有同样的问题
-
@MarcoNoronha 您能否将您的解决方案发布为您自己的答案并接受它?这将使投票更容易!
标签: java mysql hibernate hql sql-delete