当前位置: 首页 > news >正文

MySQL中,不能在一个DML(数据操纵语言,如INSERT, UPDATE, DELETE)语句中直接引用目标表进行子查询

错误示例

   <delete id="deleteOldRelations">DELETE FROM departments_closure_tableWHERE descendant IN ( SELECT descendant FROM departments_closure_tableWHERE ancestor = #{departmentId})</delete>

程序运行之后,会报错:You can't specify target table 'departments_closure_table' for update in FROM clause; nested exception is java.sql.SQLException: You can't specify target table 'departments_closure_table' for update in FROM clause] with root cause

错误原因

这个语句违反了MySQL的语法规则,因为它试图在一个DELETE语句的FROM子句中引用了正在更新的表departments_closure_table。在MySQL中,你不能在一个DML(数据操纵语言,如INSERT, UPDATE, DELETE)语句中直接引用目标表进行子查询。

如何解决

解决办法由ChatGPT生成。
可以通过以下步骤解决这个问题:

  1. 先查询出需要删除的 descendant 列表并存储在临时表中。
  2. 再删除临时表中的这些 descendant

修正后的 SQL

  1. 创建临时表并存储需要删除的 descendant 列表
<insert id="createTempTable" parameterType="long">CREATE TEMPORARY TABLE temp_descendantsASSELECT descendant FROM departments_closure_tableWHERE ancestor = #{departmentId}
</insert>
  1. 删除关系
<delete id="deleteOldRelations">DELETE FROM departments_closure_tableWHERE descendant IN (SELECT descendant FROM temp_descendants)
</delete>
  1. 删除临时表
<delete id="dropTempTable">DROP TEMPORARY TABLE temp_descendants
</delete>

完整的 XML 配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.demo.mapper.DepartmentsClosureDao"><insert id="createTempTable" parameterType="long">CREATE TEMPORARY TABLE temp_descendantsASSELECT descendant FROM departments_closure_tableWHERE ancestor = #{departmentId}</insert><delete id="deleteOldRelations">DELETE FROM departments_closure_tableWHERE descendant IN (SELECT descendant FROM temp_descendants)</delete><delete id="dropTempTable">DROP TEMPORARY TABLE temp_descendants</delete></mapper>

Java 调用代码

在 Java 代码中,按顺序调用这些方法:

package com.example.demo.service;import com.example.demo.mapper.DepartmentsClosureDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class DepartmentService {@Autowiredprivate DepartmentsClosureDao departmentsClosureDao;@Transactionalpublic void moveDepartment(Long departmentId, Long newParentId) {// 创建临时表departmentsClosureDao.createTempTable(departmentId);// 删除旧的关系departmentsClosureDao.deleteOldRelations(departmentId);// 插入新的关系 (这个方法需要你自己实现,假设它存在)departmentsClosureDao.insertNewRelations(departmentId, newParentId);// 删除临时表departmentsClosureDao.dropTempTable();}// 其他服务方法
}

总结

通过使用临时表,我们可以避免 MySQL 不允许在同一个查询中更新和查询同一张表的限制。按照上述步骤和示例代码进行实现,可以正确删除部门关系而不引发 You can't specify target table 错误。

相关文章:

  • python 第一天
  • Java----Maven详解
  • Redis常用命令大全
  • 【安装笔记-20240529-Windows-Wireshark 网络协议分析工具】
  • PHP:集成Xunsearch生成前端搜索骨架
  • 关于智慧校园安全用电监测系统的设计
  • Docker搭建FRP内网穿透服务器
  • flume-ng-sql | 支持JDK8+ | 支持Flume 1.11.0 | 使用 Kotlin 编写
  • 07-操作元素(键盘和鼠标事件)
  • 下载安装nvm,使用nvm管理node.js版本
  • Kotlin 函数式接口
  • Leetcode:无重复字符的最长子串
  • 数据结构-堆排序问题
  • Android 按上/下键,焦点会移动到第一个控件上面或最后一个控件下面的解决办法
  • VirtualBox7.x下载安装CentOS7安装网络配置
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • css属性的继承、初识值、计算值、当前值、应用值
  • HTTP--网络协议分层,http历史(二)
  • Python_网络编程
  • React的组件模式
  • Yeoman_Bower_Grunt
  • 笨办法学C 练习34:动态数组
  • 彻底搞懂浏览器Event-loop
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 浏览器缓存机制分析
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 项目管理碎碎念系列之一:干系人管理
  • 再谈express与koa的对比
  • FaaS 的简单实践
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • #162 (Div. 2)
  • #define 用法
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #NOIP 2014#Day.2 T3 解方程
  • (1)(1.13) SiK无线电高级配置(六)
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (pytorch进阶之路)扩散概率模型
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (四) Graphivz 颜色选择
  • (一)UDP基本编程步骤
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • .chm格式文件如何阅读
  • .NET Core 成都线下面基会拉开序幕
  • .NET Framework 服务实现监控可观测性最佳实践
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .Net多线程Threading相关详解
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [2]十道算法题【Java实现】
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [20190113]四校联考