커서(CURSOR)란 무엇인가?
MySQL 저장 프로시저 내부에서 결과 집합(ResultSet)을 처리해야 할 때는 커서(CURSOR)를 사용할 수 있습니다. 커서는 쿼리가 반환한 여러 행(row)을 한 줄씩 순회(iterate)하면서 각 행에 대해 원하는 작업을 수행할 수 있도록 해주는 강력한 도구입니다.
커서의 동작 흐름은 크게 다음 네 단계로 구성됩니다.
- DECLARE: 커서를 선언하고 사용할 SELECT 쿼리를 정의합니다.
- OPEN: 커서를 열어 쿼리를 실행하고 결과 집합을 준비합니다.
- FETCH: 현재 행의 값을 변수로 가져오고, 다음 행으로 포인터를 이동합니다.
- CLOSE: 모든 처리가 끝나면 커서를 닫아 리소스를 해제합니다.
예제용 테이블 준비
MySQL 저장 프로시저에서 CURSOR를 사용하는 방법을 실제로 살펴보기 위해, 아래와 같은 데이터가 담긴 student_info 테이블을 기준으로 진행하겠습니다.
mysql> Select * from student_info; +-----+---------+----------+------------+ | id | Name | Address | Subject | +-----+---------+----------+------------+ | 101 | YashPal | Amritsar | History | | 105 | Gaurav | Jaipur | Literature | | 125 | Raman | Shimla | Computers | +-----+---------+----------+------------+ 3 rows in set (0.00 sec)
커서를 활용한 저장 프로시저 작성
다음 쿼리는 테이블에 저장된 모든 주소(Address) 값을 세미콜론(;)으로 구분된 하나의 문자열 목록으로 반환하는 list_address 프로시저를 생성합니다.
mysql> Delimiter //
mysql> CREATE PROCEDURE list_address (INOUT address_list varchar(255))
-> BEGIN
-> DECLARE value_finished INTEGER DEFAULT 0;
-> DECLARE value_address varchar(100) DEFAULT "";
-> DEClARE address_cursor CURSOR FOR
-> SELECT address FROM student_info;
-> DECLARE CONTINUE HANDLER
-> FOR NOT FOUND SET value_finished = 1;
-> OPEN address_cursor;
-> get_address: LOOP
-> FETCH address_cursor INTO value_address;
-> IF value_finished = 1 THEN
-> LEAVE get_address;
-> END IF;
-> SET address_list = CONCAT(value_address,";",address_list);
-> END LOOP get_address;
-> CLOSE address_cursor;
-> END //
Query OK, 0 rows affected (0.00 sec)
코드 핵심 요소 설명
- value_finished 변수: 더 이상 읽어올 행이 없을 때 루프를 종료하기 위한 플래그 역할을 합니다.
- CONTINUE HANDLER FOR NOT FOUND: FETCH 시 더 이상 가져올 행이 없으면 자동으로
value_finished를 1로 설정하여 무한 루프를 방지합니다. - LOOP와 LEAVE:
get_address라벨이 붙은 루프에서 행을 하나씩 읽어 처리하고, 종료 조건이 충족되면LEAVE로 빠져나갑니다. - CONCAT 함수: 각 주소 값을 세미콜론 구분자와 함께 누적하여 최종 목록 문자열을 만듭니다.
프로시저 호출 및 결과 확인
이제 프로시저를 호출하면 아래와 같은 결과를 확인할 수 있습니다.
mysql> DELIMITER ; mysql> Set @address_list = ""; Query OK, 0 rows affected (0.00 sec) mysql> CALL list_address(@address_list); Query OK, 0 rows affected (0.00 sec) mysql> Select @address_list; +-------------------------+ | @address_list | +-------------------------+ | Shimla;Jaipur;Amritsar; | +-------------------------+ 1 row in set (0.00 sec)
결과를 보면 student_info 테이블의 모든 주소가 세미콜론으로 구분된 문자열로 정상적으로 반환된 것을 알 수 있습니다. 이처럼 커서를 활용하면 저장 프로시저 안에서 쿼리 결과 집합의 각 행을 유연하게 제어하고 가공할 수 있습니다.