[MySQL] Cursor

Wonjun Lee·2025년 6월 27일
💡

여러 행, 여러 열에 걸친 테이블 조회 결과를 사용하기 위해 한 행씩 처리하게 해주는 것.

커서의 처리 순서.

  1. 커서 선언 : DECLARE CURSOR
  2. 반복 조건 선언 : DECLARE CONTINUE HANDLER → 더이상 읽을 행이 없을 경우 실행.
  3. 커서 열기 : OPEN
  4. 커서에서 데이터 가져오기 : FETCH
  5. 데이터 처리
    1. 4, 5는 LOOP문을 사용해 반복 구간 지정.
  6. 커서 닫기 : CLOSE
drop procedure if exists cursorProc;

delimiter $$
create procedure cursorProc()
begin
	declare userHeight int;
    declare cnt int default 0;
    declare totalHeight int default 0;
    
    declare endOfRow boolean default false;
    
    -- 커서의 선언.
    declare userCursor cursor for select height from userTbl;
    -- 반복 조건 선언.
    declare continue handler for not found SET endOfRow = TRUE;
    
    -- 커서 열기.
    open userCursor;
    
    cursor_loop: loop
		-- 한 행 읽어 오기.
				fetch userCursor into userHeight;
		
        if endOfRow THEN
						leave cursor_loop;
        end if;
        
        SET cnt = cnt + 1;
        SET totalHeight = totalHeight + userHeight;
		end loop;
    
    select concat('고객 평균 키 ==> ', (totalHeight / cnt));
    
    -- 커서 닫기
    CLOSE userCursor;
end$$

delimiter ;

call cursorProc();
alter table userTbl add column grade varchar(5);
select * from userTbl;
select * from buyTbl;

drop procedure if exists gradeProc;

delimiter $$
create procedure gradeProc()
begin
	declare id varchar(10);
    declare hap bigint;
    declare userGrade char(5);
    
    declare endOfRow boolean default false;
    
    declare userCursor cursor for
		select U.userID, sum(price * amount)
        from userTbl U left outer join buyTbl B using(userID)
        group by U.userID, U.name;
	
    declare continue handler for not found SET endOfRow = true;
    open userCursor;
    
    cursor_loop : loop
		fetch userCursor into id, hap;
        if (endOfRow) then
			leave cursor_loop;
        end if;
        
        case
			when (hap >= 1500) then set userGrade = '최우수고객';
            when (hap >= 1000) then set userGrade = '우수고객';
            when (hap >= 1) then set userGrade = '일반고객';
            else set userGrade = '유령고객';
		end case;
        
        update userTbl set grade = userGrade where userID = id;
    end loop;
    
    close userCursor;
end$$

delimiter ;

call gradeProc();

select * from userTbl;

0개의 댓글