2016년 10월 24일 월요일

[mysql]CURSOR 사용하기

MYSQL 은 함수 또는 프로시저 내에서 CURSOR 를 제공한다.

CURSOR 루프를 통해 선택된 열 에 특정컬럼에 접근하여 로직을 수행할수 있다.

EX) 특정 팀의 특정 시즌 최근 연승또는 연패 기록을 구하는 경우



DROP FUNCTION IF EXISTS `스키마`.`함수명`;
CREATE FUNCTION `스키마`.`함수명`
--파라미터 셋팅 (팀코드,리그코드,시즌코드,시리즈코드)
(P_T_ID VARCHAR(5) , P_LE_ID INT(11), P_SEASON_ID INT(11), P_SR_ID INT(11)) 
--리턴 타입을 정의한다.

RETURNS varchar(50) CHARSET utf8
BEGIN

   --루프를 다돌았을때 핸들러에서 초기화 해주는변수
   DECLARE done INT DEFAULT FALSE;
   --승패 여부를 담기위한 변수
   DECLARE result  INT DEFAULT 1;
   --이전 승패를 담기위한 변수 0 패 1 승 가 승이기때문에 2로 기본값 셋팅
   DECLARE resultTmp  INT DEFAULT 2;
   --연승인지 연패인지를 담는 문자열변수
   DECLARE winOrLose varchar(5) DEFAULT '';
   --연승 또는 연패 카운트 수
   DECLARE cnt INT DEFAULT 0;
   --현재 이함수가 리턴 해야할 문자열
   DECLARE resultStr varchar(50) DEFAULT '';
   
   -- 선택된 값을 cur 에 셋팅하게끔 정의
   DECLARE cur CURSOR FOR
      
      -- 커서루프에서 셀렉트할 컬럼명 또는 데이터 
      -- 스케줄이 있는 게임테이블에서 
      -- 스코어와 리그,시리즈,시즌아이디 키로 조인하고
      -- 스코어에는 홈팀 원정팀 아이디에 따른 스코어가 있다.
      
      -- 해당팀이 홈일때 홈스코어가 크면 1 원정일때 원정스코어가 크면 1을 셀렉트하는
      -- 구문 요약하면  이겻을 경우 1 지면 0 이 셀렉트됨.
      SELECT 
               IF(B.H_T_ID = P_T_ID,IF(B.H_SCORE > B.V_SCORE ,1,0),IF(B.V_SCORE >                 B.H_SCORE ,1,0))  
      FROM 
      GAME A --게임의 스케줄이 있는 테이블 게임키가 있다.
      INNER JOIN LIVESCORE B ON  A.G_ID = B.G_ID AND B.STATE_SC = 3 --게임키에따         른 스코어 정보 테이블 
      WHERE
      1=1
      AND A.LE_ID = P_LE_ID
      AND A.SR_ID = P_SR_ID
      AND A.SEASON_ID = P_SEASON_ID 
      --파라미터로 받은 P_T_ID 가 홈팀 또는 원정일 때 조건 추가
      AND (A.H_T_ID = P_T_ID OR A.A_T_ID = P_T_ID)
      --최근경기부터 정렬하여 루프를 돌려야한다. 최근 연승 연패 기록이기때문.
      ORDER BY A.G_DT_KR DESC;

   --이부분은 그냥 검색에서 가따씀. 아마도 핸들러에서 로우를 못찾는 익셉션이 일어났을경우 Set 되는거 같음
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
   --커서 열기
   OPEN cur;
   
   --루프 돌리기
   read_loop: LOOP
     
     --선택된 값을 변수에 할당
     FETCH cur INTO result;
     
     -- 로우 마지막 루프를 종료
     IF done THEN
      LEAVE read_loop;

     -- 로우 마지막이 아닐경우
     ELSE
      -- 처음 로우 (resultTmp는 기본값이 2이기때문에 무조건 루프 첫바퀴에 들어옴)
       IF resultTmp = 2 THEN

          -- 연승 연패 문자열 셋팅
          IF result = 1 THEN 
              SET winOrLose = '연승';
          ELSE 
              SET winOrLose = '연패';
          END IF;
           
          --연승 카운트 증가
          SET cnt = cnt + 1;

          -- 템프에 결과 저장
          SET resultTmp = result;
       
       -- 나중 로우 
       ELSE 
          -- 연승이 끊겻을때. 앞에서 초기화 했기 때문에 0 또는 1 의 값이 들어 있다. result           -- 0 = 패 result 1 승
          -- 전 게임 결과와 이번루프에서 뽑아온 결과가 같을경우 연속 카운트 증가
          IF resultTmp = result THEN
           SET cnt = cnt + 1;
          -- 결과가 다르면 루프를 종료
          ELSE 
              LEAVE read_loop;
          END IF;
       
       END IF;
     END IF;
     
     
   --루프 구문 종료  
   END LOOP;
   --커서 닫기
   CLOSE cur;
   
   --리턴할 값 셋팅
   SET resultStr = CONCAT(cnt,winOrLose);
   RETURN resultStr;
END


아주 친절 하게 주석을 일일이 다 달아놓았다. 알아서 필요한대로 응용해서 사용할것.

추가로 mysql 에서의 함수 호출은

select  함수명(파라미터), t.col1,t.col2,.....

from table t
where ...

와 같은 방식으로 호출 하면된다.

댓글 없음:

댓글 쓰기

[lunux]리눅스 폴더별 용량 확인

리눅스 폴더별 용량 확인 조회 하고자 하는 디렉토리 리스트가있는 경로로 이동후 du -h --max-depth=1