MySQL 列出相关依赖

注释齐全,可以用来学习存储过程的条件和循环、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');

# 若存储过程存在则删除
DROP PROCEDURE IF EXISTS dep;
# 创建一个存储过程
CREATE PROCEDURE dep(jobId VARCHAR(21845))
  # 开始内容
  BEGIN
    # 定义一个变量存储合并后的字符串(逗号分隔)
    DECLARE childs VARCHAR(21845);
    # 定义一个变量存储当前查到的字符串(逗号分隔)
    DECLARE ids VARCHAR(21845);
    # 初始化字符串
    SET childs = '';

    # 逗号分隔拼接字符串,支持查到多个
    # INTO 放入 JobId
    # 拼接 % 使自带 like 模糊查找
    SELECT DISTINCT group_concat(job_id)
    INTO jobId
    FROM job_depend
    WHERE job_id LIKE concat('%', jobId, '%');

    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';

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术之路

sqlserver 各种判断是否存在(表名、函数、存储过程.......)

库是否存在 if exists(select * from master..sysdatabases where name=N'库名') print 'exi...

17710
来自专栏battcn

MySQL - EXPLAIN详解

EXPLAIN: 为 SELECT语句中使用到的每个表返回一条信息。它按照MySQL在处理语句时读取它们的顺序列出这些表。MySQL使用循环嵌套算法解析所有连接...

872
来自专栏编程心路

写给新手的Mysql入门指南(一)

关键字最好大写,这样便于阅读。可以用windows的cmd运行工具对数据库操作,前提是mysql的安装目录的子目录bin的路径添加导论系统变量PATH中,mys...

793
来自专栏FSociety

SQL中查询效率优化

索引是独立于表的一中物理存储结构,当我们语句中用到索引的字段的时候,数据库会首先去索引中查找满足条件的数据的索引值(相当于页码),然后在根据索引值去表中筛选出我...

943
来自专栏python学习路

二、Mysq(二)

内置函数 1、字符串函数 查看字符的ascii码值ascii(str),str是空串时返回0 select ascii('a'); 查看ascii码值对应的字符...

2836
来自专栏MYSQL轻松学

insert事务产生duplicate key error引发的死锁分析

先看程序报错: 2017-06-12 21:18:40.856 [ForkJoinPool.commonPool-worker-12] ERROR com....

4114
来自专栏十月梦想

Promise对象、传参以及错误处理

在大部分情况下我们的程序都是在进行异步操作,需要嵌套多次callback,使得程序变得复杂!ES6中提供了Promise对象,将非阻塞I/O变为阻塞I/O,把异...

851
来自专栏闻道于事

PL/SQL 编程(三 )程序包和包体,触发器,视图,索引

一、程序包和包体 程序包(package):存储在数据库中的一组子程序、变量定义。在包中的子程序可以被其它程序包或子程序调用。但如果声明的是局部子程序,则只能在...

3127
来自专栏Java帮帮-微信公众号-技术文章全总结

Oracle应用实战五——SQL查询

Oracle SQL SQL学习是重点,请仔细阅读。 ? O Oracle 结构化查询语言(Structured Query Language)简称SQL(...

3234
来自专栏源哥的专栏

oracle中如何删除重复数据

        我们可能会出现这种情况,某个表原来设计不周全,导致表里面的数据数据重复,那么,如何对重复的数据进行删除呢?         重复的数据可能有这样...

723

扫码关注云+社区