zoukankan      html  css  js  c++  java
  • MySql 使用递归函数时遇到的级联删除问题

    以下两段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结束。不仅提高了效率,还避免了错误。

  • 相关阅读:
    暑假第一周总结
    洛谷P3378 【模板】堆 题解 堆(Heap)入门题
    洛谷P2170 选学霸 题解 并查集+01背包
    洛谷P1433 吃奶酪 题解 状态压缩DP
    洛谷P2835 刻录光盘 题解 点的度数+并查集
    洛谷P1991 无线通讯网 题解 并查集+二分答案
    洛谷P4185 [USACO18JAN]MooTube G 题解 并查集
    洛谷P4145 上帝造题的七分钟2 / 花神游历各国 题解 线段树+懒惰标记
    洛谷P2658 汽车拉力比赛 题解 二分答案+搜索
    洛谷P1546 最短网络 Agri-Net 题解 最小生成树/Prim算法
  • 原文地址:https://www.cnblogs.com/flying607/p/4854048.html
Copyright © 2011-2022 走看看