DROP PROCEDURE IF EXISTS my_loop_procedure;
delimiter $$
CREATE PROCEDURE my_loop_procedure()
BEGIN
SET @counter = 0;
SET @result = '';
# 'my_loop'이라는 이름의 Loop을 시작한다.
# loop label은 생략 가능
my_loop: LOOP
IF @counter > 10 THEN
LEAVE my_loop; # 조건이 true면 실행 중인 my_loop를 break
END IF;
SET @counter = @counter + 1;
IF (@counter mod 2) THEN
# 2로 나누어 떨어지면, 이하의 내용을 실행하지 않고
# 다시 my_loop를 continue
ITERATE my_loop;
ELSE
SET @result = CONCAT(@Result, @counter, ',');
END IF;
END LOOP;
# LEAVE loop하면 결과 출력
SELECT @result;
END $$
delimiter ;
# 프로시저 사용
CALL my_loop_procedure();
LEAVE
키워드는 프로시저
를 종료시키는 경우에도 사용된다.LEAVE
키워드를 사용하려면 loop_label을 필수로 사용해야 하는 듯 하다.delimiter $$
CREATE PROCEDURE strange_counter(
IN from_number INT,
IN to_number INT,
OUT diff INT
)
BEGIN
SET diff = -1;
my_while_loop: WHILE from_number >= to_number DO
SET diff = diff + 1;
SET from_number = from_number - 1;
END WHILE;
END $$
delimiter ;
# 프로시저 호출
CALL strange_counter(50, 30, @diff);
SELECT @diff; # 20
WHILE
도 마찬가지로 label을 부여할 수 있다.
결과 파라미터는 프로시저 호출 시점의 값과 상관없이 항상 Null로 초기화되는 것 같다.
따라서 프로시저 내부에서 명시적으로 초기화를 해줘야 한다.
안 그러면 null + 1 = null
때문에 결과값이 null이 된다.
REPEAT
은 do-while
과 비슷한 구조를 가지나,
반복 조건
이 아닌 정지 조건
을 명시해야 한다는 차이가 있다.
delimiter $$
CREATE PROCEDURE RepeatDemo()
BEGIN
SET @counter = 1;
SET @result = '';
# 일단 무조건 한 번 실행
REPEAT
SET @result = CONCAT(@result, @counter,',');
SET @counter = @counter + 1;
# 정지 조건에 도달할 때 까지 REPEAT
UNTIL @counter >= 10
END REPEAT;
SELECT result; # 1 ~ '9' 까지 값을 콤마로 연결한 결과값
END$$
delimiter ;
delimiter $$
CREATE PROCEDURE is_adult(age int, OUT category varchar(5))
BEGIN
IF age >= 19 THEN
SET category = 'yes'
END IF;
END $$
delimiter ;
# 프로시저 사용
SET @isAdult = 'no';
CALL is_adult(20, @isAdult);
SELECT @isAdult; # yes
만약 IF문의 조건에 부합하지 않으면 category(@isAdult)는 null로 설정된다.
delimiter $$
CREATE PROCEDURE is_adult(age int, OUT category varchar(5))
BEGIN
IF age >= 19 THEN
SET category = 'yes';
ELSE
SET category = 'no';
END IF;
END $$
delimiter ;
# 프로시저 사용
CALL is_adult(10, @isAdult);
SELECT @isAdult; # no
delimiter $$
CREATE PROCEDURE age_category(age int, OUT category varchar(10))
BEGIN
IF age >= 19 THEN
SET category = 'adult';
ELSEIF age >= 10 THEN
SET category = 'teenager';
ELSE
SET category = 'baby';
END IF;
END $$
delimiter ;
# 프로시저 사용
CALL age_category(15, @category);
SELECT @category; # teenager
크게 두 가지 사용법으로 구분된다.
#
delimiter $$
CREATE PROCEDURE age_category(age int, OUT category varchar(10))
BEGIN
CASE age
WHEN 19 THEN
SET category = 'nineteen';
WHEN 18 THEN
SET category = 'eighteen';
ELSE
SET category = 'I_Don''t_Know';
END CASE;
END $$
delimiter ;
ELSE
부분을 생략할 수는 있는데, 앞선 CASE 조건에서 필터링되지 않는다면 Case not found 에러가 발생한다. (CASE 조건에서 필터링되면 문제 X)
#
delimiter $$
CREATE PROCEDURE age_category(age int, OUT category varchar(10))
BEGIN
CASE
WHEN age >= 19 THEN
SET category = 'adult';
WHEN age >= 10 THEN
SET category = 'teenager';
ELSE
SET category = 'baby';
END CASE;
END $$
delimiter ;
Searched CASE Statement
도 Simple CASE Statement
과 동일하게 ELSE 없을 때 문제
가 발생한다.