mysql自定義函數遞歸查詢部門層級


最近有個項目需要在很多前端頁面顯示當前員工的部門,但是這個部門是顯示當前部門的所有父級部門,比如當前為研發部,在前台頁面需要顯示為

“集團公司>子公司>研發部” 的格式,因為很多頁面都需要這種數據,在查詢時關聯查詢可能比較麻煩,所以選擇自定義一個mysql函數來查詢這種格式。

現在需要的是從子級查詢父級部門,是從下往上查,可能父級部門只有一個,也可能有多個父級部門,所以我們需要for循環來遞歸查詢。

為了舉個栗子,新建表結構及插入數據

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for sa_org
-- ----------------------------
DROP TABLE IF EXISTS `sa_org`;
CREATE TABLE `sa_org`  (
  `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `p_org_id` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `org_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sa_org
-- ----------------------------
INSERT INTO `sa_org` VALUES ('27193728124848239', '0', '集團公司');
INSERT INTO `sa_org` VALUES ('27193728124848240', '27193728124848239', '子公司1');
INSERT INTO `sa_org` VALUES ('27193728124848241', '27193728124848240', '合規部');

SET FOREIGN_KEY_CHECKS = 1;

這里插入三條數據,比如當前某個員工是合規部,需要顯示為如下格式:

這里我們設置最頂級的部門id為0,當當前部門的id為0時默認退出循環,所以我們可以這樣寫函數:

DROP FUNCTION IF EXISTS getOrgParent;

CREATE  FUNCTION `getOrgParent`(orgId varchar(100)) RETURNS varchar(1000) CHARSET utf8
        
BEGIN 
DECLARE orgNamePath VARCHAR(1000);
DECLARE pOrgId VARCHAR(32);
DECLARE orgName VARCHAR(128);

SET orgNamePath = '';
SET pOrgId = orgId;
set orgName = '';

WHILE pOrgId <> '0'
DO

SELECT p_org_id, org_name INTO pOrgId, orgName FROM sa_org WHERE id = pOrgId;

IF orgNamePath = '' THEN
    SET orgNamePath = orgName;
ELSE
    SET orgNamePath = CONCAT(orgName, '>', orgNamePath);
END IF;

END WHILE;
RETURN orgNamePath;
END

執行完成,查詢試一下:

select getOrgParent('27193728124848241')

select getOrgParent('27193728124848240')

 可以看到實現了我們的需求,在查詢表格數據時,直接使用這個函數就可以將org_id變為部門層級展示了。

但是當我們輸入一個不存在於這個表的數據時,會發現這條查詢一直在執行,構成了死循環,所以我們改成如下:

drop  FUNCTION if EXISTS `getOrgParent`;
CREATE FUNCTION `getOrgParent`(orgId varchar(100)) RETURNS varchar(1000) CHARSET utf8
BEGIN 
DECLARE orgNamePath VARCHAR(1000);
DECLARE pOrgId VARCHAR(32);
DECLARE orgName VARCHAR(128);
DECLARE count INT;

SET orgNamePath = '';
SET pOrgId = orgId;
set orgName = '';
set count = 1;

WHILE pOrgId <> '0' and count <> 0
DO

SELECT p_org_id, org_name, count(1) INTO pOrgId, orgName, count FROM sa_org WHERE id = pOrgId;

IF orgNamePath = '' THEN
    SET orgNamePath = orgName;
ELSE
    SET orgNamePath = CONCAT(orgName, '>', orgNamePath);
END IF;

END WHILE;
RETURN orgNamePath;
END

 可以看到即使現在這條數據不存在也不會死循環了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM