본 글은 MariaDB 10.5.11 을 기준으로 작성되었음을 알려드립니다.
Procedure를 만들어 작업 처리를 하다보면 Cursor를 여러개 사용하여
다중 반복문을 돌려야할 때가 있습니다.
그때 우리는 크게 2가지의 해결책을 사용해볼 수 있습니다.
MariaDB 에는 block 이라는 예약어를 통해 statement를 지정해줄 수 있습니다.
아래 예시와 함께 보도록 하겠습니다.
DELIMITER $$
CREATE PROCEDURE PR_TEST_EXAMPLE()
BLOCK_1:
BEGIN
DECLARE done_1 boolean DEFAULT false;
DECLARE v_col1 varchar(100);
DECLARE v_col2 varchar(100);
DECLARE cur1 cursor for select idx, data
FROM tb_dummy_one;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done_1 := true;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK ;
END;
START TRANSACTION;
OPEN cur1;
LOOP1:
LOOP
-- // FETCH
FETCH cur1 INTO v_col1,
v_col2;
-- // LOOP CONDITION CHECKSUM
IF done_1 THEN
CLOSE cur1;
LEAVE LOOP1;
END IF;
-- // COMMAND (CRUD, ETC ...)
BLOCK_2:
BEGIN
DECLARE done_2 boolean DEFAULT false;
DECLARE v_col3 varchar(100);
DECLARE v_col4 varchar(100);
DECLARE cur2 CURSOR FOR SELECT idx, data_2
FROM tb_dummy_two;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done_2 := true;
OPEN cur2;
LOOP2:
LOOP
-- // FETCH
FETCH cur2 INTO v_col3,
v_col4;
-- // LOOP CONDITION CHECKSUM
IF done_2 THEN
CLOSE cur2;
LEAVE LOOP2;
END IF;
-- // COMMAND (CRUD, ETC ...)
END LOOP LOOP2;
END BLOCK_2;
END LOOP LOOP1;
COMMIT;
END BLOCK_1;
$$
DELIMITER ;
각자의 장단점이 있어, 무엇이 더 낫다 라고 딱 잘라 말씀 드리기엔 어렵습니다.
본인의 쿼리 및 개발 취향에 맞는 방법을 채택하여 사용하시면 됩니다.
Loop 탈출 조건을 위한 변수의 값을 통제하여, 반복문을 제어합니다.
DELIMITER $$
CREATE PROCEDURE PR_TEST_EXAMPLE()
BEGIN
DECLARE done boolean DEFAULT false;
DECLARE v_col1 varchar(100);
DECLARE v_col2 varchar(100);
DECLARE v_col3 varchar(100);
DECLARE v_col4 varchar(100);
DECLARE cur1 cursor for select idx, data
FROM tb_dummy_one;
DECLARE cur2 CURSOR FOR SELECT idx, data_2
FROM tb_dummy_two;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := true;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK ;
END;
START TRANSACTION;
OPEN cur1;
LOOP1:
LOOP
-- // FETCH
FETCH cur1 INTO v_col1,
v_col2;
-- // LOOP CONDITION CHECKSUM
IF done THEN
CLOSE cur1;
LEAVE LOOP1;
END IF;
-- // COMMAND (CRUD, ETC ...)
OPEN cur2;
LOOP2:
LOOP
-- // FETCH
FETCH cur2 INTO v_col3,
v_col4;
-- // LOOP CONDITION CHECKSUM
IF done THEN
set done := false;
CLOSE cur2;
LEAVE LOOP2;
END IF;
-- // COMMAND (CRUD, ETC ...)
END LOOP LOOP2;
END LOOP LOOP1;
COMMIT;
END;
$$
DELIMITER ;
위 예시들을 보시면 주석을 달아놓은 부분이 있습니다.
작업을 진행하시다 보면, 길어진 쿼리양에 의해 가독성이 많이 떨어지는데요.
그에 따라, Fetch와, 작업수행 및 반복문 탈출 조건의 체크가
꼬이게 되면, 원치 않는 방향으로 반복문이
한번 더 수행된다던지 하는 경우가 있습니다.
이때, 저 순서만 기억해주시면 Cursor 와 Loop 사용 중 그러한 불상사를 피할 수 있습니다.
[Mariadb] Multi Row insert 문 (0) | 2023.07.26 |
---|---|
[MariaDB] timezone 가지고 놀기 feat. CONVERT_TZ (0) | 2022.11.03 |
[Mariadb] function 리턴 값에 한글이 깨질때 해결방법 (0) | 2022.06.22 |
[MariaDB] 년월일 시분초 날짜 포맷 지정해서 가지고 오기 (0) | 2022.04.11 |
[MariaDB] table 과 column 에 Comment 넣는 방법 (0) | 2022.04.08 |