데이터베이스

[mysql/mariadb] 계층쿼리 함수생성 및 호출로 구현

엉으니 2019. 5. 23. 15:12

계층쿼리를 만드는 방법은 함수로 구현하는 방법과 그냥 생쿼리로 짜는 방법이 있다.

그 중 함수로 구현하는 방법을 정리했다.

함수도 int파라미터로 받는 방법과 varchar로 받는 방법이 있는데

두 방법이 큰 차이가 있지는 않다.

 

1. varchar파라미터로 받는 방법

DROP FUNCTION IF EXISTS GET_DEPT_TREE;

DELIMITER $$
CREATE FUNCTION GET_DEPT_TREE(value VARCHAR(50)) RETURNS VARCHAR(50) //파라미터, 리턴타입 맞춰준다.
NOT DETERMINISTIC
READS SQL DATA

BEGIN
        DECLARE _menuCd VARCHAR(50); //함수내 변수 메뉴코드
        DECLARE _parnCd VARCHAR(50); //함수내 변수 부모코드 
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @MENU_CD = NULL; //@MENU_CD는 컬럼명으로 맞춰준다.

        SET _parnCd = @MENU_CD;
        SET _menuCd = '';
        
        IF @MENU_CD IS NULL THEN
                RETURN NULL;
        END IF;

       LOOP
                SELECT  MIN(MENU_CD)
                INTO    @MENU_CD
                FROM    YE_MENU_MGR
                WHERE   PARN_CD = _parnCd 
                        AND MENU_CD > _menuCd;
                IF @MENU_CD IS NOT NULL OR _parnCd = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @MENU_CD;
                END IF;
                SET @level := @level - 1;
                SELECT MENU_CD, PARN_CD
                INTO    _menuCd, _parnCd
                FROM    YE_MENU_MGR
                WHERE   MENU_CD = _parnCd;
        END LOOP;
END

 

2. int파라미터로 받는 방법

참고 블로그에서 가져온 내용이다.

하지만 varchar파라미터와 내용이 아주 유사하다.

변수 타입만 맞춰주면 된다.

 

DELIMITER $$
CREATE FUNCTION hierarchy_connect_by_parentIdx_eq_prior_idx(value VARCHAR(50)) RETURNS VARCHAR(50)
NOT DETERMINISTIC 
READS SQL DATA 
BEGIN 
DECLARE _idx INT; 
DECLARE _parentIdx INT; 
DECLARE _next INT; 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET @idx = NULL; 

SET _parentIdx = @idx; 
SET _idx = -1; 

IF @idx IS NULL THEN 
RETURN NULL; 
END IF; 

LOOP 
SELECT MIN(idx) 
INTO @idx FROM Category 
WHERE parentIdx = _parentIdx 
AND idx > _idx; 
IF @idx IS NOT NULL OR _parentIdx = @start_with THEN 
SET @level = @level + 1; 
RETURN @idx; 
END IF; 
SET @level := @level - 1; 
SELECT idx, parentIdx 
INTO _idx, _parentIdx 
FROM Category 
WHERE idx = _parentIdx; 
END LOOP; END 
$$ DELIMITER ;

출처: https://wookmania.tistory.com/96 [코드의추억]

 

3. 함수 사용

계층쿼리의 사용 이유는 level을 뽑는데 있다.

그 level을 뽑는 쿼리 예시다.

SELECT  
dc.MENU_CD
, CONCAT(REPEAT('       ', dc2.lev-1), MENU_NM) AS MENU_NM, PARN_CD, CAST(dc2.lev AS CHAR) AS lev
FROM    (
        SELECT  GET_DEPT_TREE(MENU_CD) AS MENU_CD, @level as lev
        FROM    (
                SELECT  @start_with := '',
                        @MENU_CD := @start_with,
                        @level := 0
                ) vars, YE_MENU_MGR
        WHERE   @MENU_CD IS NOT NULL
        ) dc2
JOIN    YE_MENU_MGR dc
ON      dc.MENU_CD = dc2.MENU_CD;

level별로 탭을 넣어 표시하도록 했다.

 

반응형

'데이터베이스' 카테고리의 다른 글

[mysql/mariadb] 계층쿼리 RECURSIVE로 구현  (0) 2019.05.27
[ORACLE] 시노님(SYNONYM)  (0) 2017.09.29
[mysql] loop로 더미데이터 삽입  (1) 2016.03.03
[mysql] VIEW  (0) 2016.02.18
[mysql] UNION  (0) 2016.02.18