美文网首页我爱编程
MySQL 列出相关依赖

MySQL 列出相关依赖

作者: 林万程 | 来源:发表于2018-04-06 08:49 被阅读111次

    注释齐全,可以用来学习存储过程的条件和循环、SQL条件


    结果展示
    DROP TABLE IF EXISTS test.job_depend;
    # 创建测试表
    CREATE TABLE `job_depend` (
      `sn_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '行号',
      `job_id` varchar(20) DEFAULT NULL COMMENT '作业ID',
      `depend_job_id` varchar(20) DEFAULT NULL COMMENT '依赖作业',
      PRIMARY KEY (`sn_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='作业依赖';
    
    # 插入测试数据
    INSERT INTO test.job_depend (job_id, depend_job_id) VALUES ('b', 'a');
    INSERT INTO test.job_depend (job_id, depend_job_id) VALUES ('c', 'b');
    INSERT INTO test.job_depend (job_id, depend_job_id) VALUES ('c', 's');
    INSERT INTO test.job_depend (job_id, depend_job_id) VALUES ('s', 'c');
    
    # 设置连接函数最大长度(默认1024)
    SET GLOBAL group_concat_max_len = 16777215;
    
    # TINYTEXT 255 TEXT 65535 MEDIUMTEXT 16777215 LONGTEXT 4294967295
    # 若存储过程存在则删除
    DROP PROCEDURE IF EXISTS dep;
    # 创建一个存储过程
    CREATE PROCEDURE dep(jobId MEDIUMTEXT)
      # 开始内容
      BEGIN
        # 定义一个变量存储合并后的字符串(逗号分隔)
        DECLARE childs MEDIUMTEXT;
        # 定义一个变量存储当前查到的字符串(逗号分隔)
        DECLARE ids MEDIUMTEXT;
        # 初始化字符串
        SET childs = '';
    
        SET jobId = replace(jobId, '\n', '');
        SET jobId = replace(jobId, '\r', '');
    
        IF instr(jobId, ',') = 0
        THEN
          # 逗号分隔拼接字符串,支持查到多个
          # INTO 放入 JobId
          # 拼接 % 使自带 like 模糊查找
          SELECT DISTINCT group_concat(job_id)
              INTO jobId
          FROM job_depend
          WHERE job_id LIKE concat('%', jobId, '%');
        END IF;
    
        SET ids = jobId;
    
        # 当前查到的字符串不为空时
        WHILE ids IS NOT NULL DO
          # 拼接字符串
          SET childs = concat(ids, ',', childs);
    
          # SELECT 不重复 拼接字段,默认逗号分隔
          # INTO 放入 当前查找的字符串
          # WHERE (查找值, 字符串集合) 且没有在合并字符串
          SELECT DISTINCT group_concat(depend_job_id)
          INTO ids
          FROM job_depend
          WHERE find_in_set(job_id, ids) > 0
                AND NOT find_in_set(depend_job_id, childs);
        END WHILE;
    
        SET ids = jobId;
    
        # 反过来查找依赖 ids 的
        WHILE ids IS NOT NULL DO
          SELECT DISTINCT group_concat(job_id)
          INTO ids
          FROM job_depend
          WHERE find_in_set(depend_job_id, ids) > 0
                AND NOT find_in_set(job_id, childs);
          IF ids IS NOT NULL THEN
            SET childs = concat(childs, ',', ids);
          END IF;
        END WHILE;
    
        SELECT
          # DISTINCT
          # 如果 job_id 是查询传入的 jobId
          # SQL 下的 IF 条件写法
          CASE find_in_set(job_id, jobId) > 0
          # 为真 则标记 =>
          WHEN TRUE THEN '=>'
          # 否则不显示任何内容
          ELSE '' END AS f,
          job_id,
          depend_job_id
        FROM job_depend
        WHERE find_in_set(job_id, childs)
        # 按下面依赖上面排序(需查找位置的子字符串, 大字符串)
        ORDER BY instr(job_id, jobId);
      END;
    
    # 使用例子
    CALL dep('c');
    
    # 查询本程序
    SELECT
      SPECIFIC_NAME,
      ROUTINE_TYPE
    FROM information_schema.ROUTINES
    WHERE SPECIFIC_NAME = 'dep';
    

    相关文章

      网友评论

        本文标题:MySQL 列出相关依赖

        本文链接:https://www.haomeiwen.com/subject/tupjhftx.html