Oracle 的一次 MyBatis 查询中的两个删除?
Posted
技术标签:
【中文标题】Oracle 的一次 MyBatis 查询中的两个删除?【英文标题】:Two delete in one MyBatis query for Oracle? 【发布时间】:2020-11-02 00:05:40 【问题描述】:我想从两个表中删除两行。从每个一个行。在 XML 映射器中。MyBatis executing multiple sql statements in one go, is that possible? 触及了这个问题,但答案不是关于 XML 映射器或 - 看下面 - 不适用于 Oracle。
按照上面提到的,我需要写:
<delete id="removeReportRecord" >
DELETE FROM S01_SESTAVA WHERE (id_s01_sestava = #idReport);
DELETE FROM S02_DATA WHERE (id_s01_sestava = #idReport);
</delete >
...
int removeReportRecord(Long idReport);
但这不适用于 Oracle。我试过没有“;”在第三行,或者在两个删除操作上(MyBatis with Oracle 不喜欢结尾的“;”)或在界面中为参数使用注释 - 我总是有相同的消息:
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
如果我改为使用两个后续查询:
<delete id="removeReportRecord" >
DELETE FROM S01_SESTAVA WHERE (id_s01_sestava = #idReport)
</delete >
<delete id="removeReportData" >
DELETE FROM S02_DATA WHERE (id_s01_sestava = #idReport)
</delete >
...
int removeReportRecord(Long idReport);
int removeReportData(Long idReport);
没问题,一切正常。我已经用@Transactional 介绍了这两个操作,它可以工作并且看起来很安全,但是如果我真的需要在一个查询中使用多个 SQL 操作符,我该如何使用这些 MyBatis XML + Oracle 呢?我是不是做错了什么?
【问题讨论】:
你看到了吗:***.com/a/8338725/910736 根据@JamesB 链接的答案,Oracle 不支持在一个命令中使用多个语句,但您可以发送包含多个 SQL 语句的单个 PL/SQL 匿名块。CALL BEGIN DELETE FROM table1 WHERE ...; DELETE FROM table2 WHERE ...; END
我会避开这个功能。只需单独运行每个 SQL 并在晚上睡个好觉。我个人不喜欢在凌晨 2 点应用程序崩溃时随叫随到,因为 DevOps 更改了数据源 URL——迁移、升级、部署、新版本等——并删除了标志。
@JamesB 我在我的问题中提到了那个问题,这是第一行,你没注意到吗?当然,我阅读了所有我能找到的东西。提出其他技术解决方案对我来说没有任何价值——我不想在没有必要的情况下扩大使用方法的范围。
@MT0 在那个答案中并不是说 Oracle 在 XML 映射器中不支持它。只提出了另一种工作方式。谢谢你的信息,这可能是答案。
【参考方案1】:
是否支持执行多条语句取决于驱动程序。 Oracle的JDBC驱动支持方式如下(用ojdbc8 19.8.0.0测试)。
<delete id="removeReportRecord">
BEGIN
DELETE FROM S01_SESTAVA WHERE (id_s01_sestava = #idReport);
DELETE FROM S02_DATA WHERE (id_s01_sestava = #idReport);
END;
</delete >
请注意,使用这种方法,该方法返回 -1
而不是删除的行数,因为驱动程序从 PreparedStatement#getUpdateCount()
返回 -1
。
【讨论】:
谢谢。我在您的解决方案中看到了更多优点。如果我不使用这些开始/结束括号,我必须删除“;”从 Oracle SQL 查询让 MyBatis 接受它们。正如我所见,使用这些括号,支持标准的 Oracle 语法。因此,最好将它们用于单个查询 - 因此我们可以使用 SQL 客户端中的查询来测试 unchanged。 很高兴知道它有帮助! :D以上是关于Oracle 的一次 MyBatis 查询中的两个删除?的主要内容,如果未能解决你的问题,请参考以下文章
java中使用mybatis和oracle 查询数据时比如我第一次点击页面查询 返回1,2