以下两段SQL的写法看似相同,结果效果却是不同的

写法A

DELETE OM_ORGANIZATION,
OM_POSITION
FROM
OM_ORGANIZATION
LEFT JOIN OM_POSITION ON OM_POSITION.ORG_ID = OM_ORGANIZATION.ORG_ID
WHERE
FIND_IN_SET(
          OM_ORGANIZATION.ORG_ID,
          OM_ORGANIZATION_QUERY_CHILDREN ('52037b7c-0f01-41f6-849f-4f99ad8f2422')
)

这个写法是不正确的,先来介绍一下这个

OM_ORGANIZATION_QUERY_CHILDREN 

函数

BEGIN
DECLARE sTemp VARCHAR(4000);
DECLARE sTempChd VARCHAR(4000); SET sTemp = '$';
SET sTempChd = id; WHILE sTempChd is not NULL DO
SET sTemp = CONCAT(sTemp,',',sTempChd);
SELECT group_concat(ORG_ID) INTO sTempChd FROM OM_ORGANIZATION where FIND_IN_SET(PARENT_ORG_ID,sTempChd)>0;
END WHILE;
return sTemp;
END

id(VARCHAR(40))是这个函数的参数

这个函数的执行结果是返回一个拼起来的字符串,字符串根据主键ORG_ID、父节点主键PARENT_ORG_ID两个字段,递归查询出OM_ORGANIZATION中所有以传入参数作为根节点的主键,然后拼成一个类似 【1,2,3,4】的可供FIND_IN_SET使用的字符串(这里定义成VARCHAR(4000))。

写法A中:每删除一条数据都有可能造成OM_ORGANIZATION_QUERY_CHILDREN ('1')这个函数的执行结果变化,

假设删除第一条的时候,这个函数的执行结果是【1,2,3】,其中’2‘的父节点是’1‘,’3‘的父节点也是’1‘,那么在删除完’2‘之后,函数的结果变成了【1,3】,而后边与’2‘存在关系的OM_POSITION就无法被删掉了。

正确的写法应该如下:

写法B:

DELETE OM_ORGANIZATION,
OM_POSITION
FROM
(
SELECT
ORG_ID
FROM
OM_ORGANIZATION
WHERE
FIND_IN_SET(
          OM_ORGANIZATION.ORG_ID,
          OM_ORGANIZATION_QUERY_CHILDREN ('52037b7c-0f01-41f6-849f-4f99ad8f2422')
)
) T
INNER JOIN OM_ORGANIZATION ON T.ORG_ID = OM_ORGANIZATION.ORG_ID
LEFT JOIN OM_POSITION ON OM_POSITION.ORG_ID = OM_ORGANIZATION.ORG_ID

这样,函数只执行一遍,其结果将一直保持不变,直到SQL结束。不仅提高了效率,还避免了错误。

MySql 使用递归函数时遇到的级联删除问题的更多相关文章

  1. [原创]MYSQL中利用外键实现级联删除和更新

    MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定 ...

  2. MySQL中利用外键实现级联删除、更新

    MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定在删除.更新父表时,对子表进行的相应操作 ...

  3. sql server删除数据时如何进行级联删除

    可以在创建外键约束时直接设置级联删除

  4. mysql级联删除更新

    首先,目前在产品环境可用的MySQL版本(指4.0.x和4.1.x)中,只有InnoDB引擎才允许使用外键,所以,我们的数据表必须使用InnoDB引擎. 下面,我们先创建以下测试用数据库表: CREA ...

  5. 【Python】Django数据模型、级联删除、级联更新、ER图导出等

    在本文中,我们将向读者详细介绍如何在更新和删除父表数据的同时,触发有关子表数据的级联更新和删除操作.您将看到当使用InnoDB表的时候,借助于外键约束就可以轻松搞定这一过程. 一.利用外键约束更新并删 ...

  6. MySQL级联删除的问题

    一.FOREIGN KEY 的定义分为两种:列级约束和表级约束 .列及约束的话,可以在列定义的同时,定义外键约束.比如 如果有2张表,主表:T1(A1 )) 要在从表T2中定义外键列这可以: Crea ...

  7. MySQL外键及级联删除 && 表的存储引擎与创建索引 && 删除数据库和表

    Messages表: mysql>create table Messages( ->message_id int auto_increment primary key, ->user ...

  8. Mysql实现级联操作(级联更新、级联删除)

    一.首先创建两张表stu,sc create table stu( sid int UNSIGNED primary key auto_increment, name ) not null) TYPE ...

  9. MySQL外键设置 级联删除

    . cascade方式在父表上update/delete记录时,同步update/delete掉子表的匹配记录 . set null方式在父表上update/delete记录时,将子表上匹配记录的列设 ...

随机推荐

  1. 利用ab压力工具对服务器进行压力测试

    假如我们需要对http://letv.com进行压力测试,指定请求总数为100,并发用户数为10,我们可以以下面的方式进行测试 $ ab -n 100 -c 10 http://letv.com/Th ...

  2. 2019-11-29-msbuild-项目文件常用判断条件

    title author date CreateTime categories msbuild 项目文件常用判断条件 lindexi 2019-11-29 08:36:48 +0800 2019-7- ...

  3. JAVA中如何定义自定义注解

    了解注解 注解是Java1.5,JDK5.0引用的技术,与类,接口,枚举处于同一层次 .它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明,注释 . 在Java中,自带 ...

  4. Linux学习--第十三天--日志、系统运行级别、grub加密

    日志 rsyslogd取代了syslogd. /var/log/cron #定时任务相关日志 /var/log/cups #打印信息相关日志 /var/log/dmesg #开机内核自检相关日志,dm ...

  5. python-函数2(调用)

    python-函数2(调用) 1.实参和形参调用 2.默认调用 3.参数驵调用 1.实参和形参调用 def test5(x,y): #形参 print(x) print(y) y=1 x=2 test ...

  6. Linux部署Redis及PHP-redis扩展

    Redis是一个key-value存储系统,属于我们常说的NoSQL.它遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.它常用在缓存.队列.P ...

  7. C++ STL(二)vector的用法

    ##### vector的定义 ```#include <iostream>#include <string>#include <vector>using name ...

  8. jquery easyui datagrid 远程加载数据----把主键渲染为值遇到的问题及解决方案

    起因:数据库中一些字段存的是代表具体值的数字,需要渲染为具体值 monggodb中的字典 mysql中存放的值为:expertin代表教练擅长的搏击技能 jquery easyui中的相关代码如下:用 ...

  9. Idea创建多模块依赖Maven项目

    idea 创建多模块依赖Maven项目   本来网上的教程还算多,但是本着自己有的才是自己的原则,还是自己写一份的好,虽然可能自己也不会真的用得着. 1. 创建一个新maven项目 2. 3. 输入g ...

  10. jvm——分层编译

    https://www.cnblogs.com/andy-zhou/p/5327288.html 分层编译根据编译器编译.优化的规模与耗时,划分出不同的编译层次: 第0层:程序解释执行,解释器不开启监 ...