728x90
CURSOR : 테이블을 한 줄씩 읽어서 다른 작업을 진행할 때 사용
커서 구문
-- FOR SELECT문 -> 한 줄씩 읽을 타겟 데이터를 SELECT함
DECLARE 커서이름 CURSOR FOR
SELECT문
OPEN 커서이름
-- FETCH문 : 한 줄 읽음
FETCH NEXT FROM 커서이름 INTO @SELECT된컬럼들, ...
WHILE(@@FETCH_STATUS = 0)
BEGIN
작업 진행(ex. SELECT, INSERT, UPDATE, DELETE, ... )
-- 다음 줄 읽음
FETCH NEXT FROM 커서이름 INTO @SELECT된컬럼들, ...
END
CLOSE 커서이름
DEALLOCATE 커서이름
이중 커서 예시
![]() |
예시로 이런 헤더, 디테일 테이블이 있다고 가정.
헤더 테이블의 PK는 CODE
디테일 테이블의 PK는 CODE, SEQ 로 헤더의 내역을 관리할 수 있음 → 헤더의 CODE = 디테일의 CODE 임
두 테이블을 모두 조회하도록 CURSOR 작성
-- 임시 테이블 생성
CREATE TABLE #HDR (
CODE NVARCHAR(1) NOT NULL, -- PK용
FLAG NVARCHAR(1) NULL
CREATE TABLE #DTL (
CODE NVARCHAR(1) NOT NULL, -- PK용
SEQ INT NOT NULL, -- PK용
CONTENT NVARCHAR(20) NULL
)
INSERT INTO #HDR VALUES('A', 'Y')
INSERT INTO #HDR VALUES('B', 'N')
INSERT INTO #DTL VALUES('A', 1, 'TEST')
INSERT INTO #DTL VALUES('A', 2, 'CONTENT')
INSERT INTO #DTL VALUES('A', 3, 'EXAMPLE')
INSERT INTO #DTL VALUES('B', 1, 'PRACTICE')
INSERT INTO #DTL VALUES('B', 2, 'SLEEPY')
-- 변수 선언 ----------------------------------------
DECLARE
-- 커서로 읽을 SELECT문의 모든 컬럼을 선언
@CODE NVARCHAR(1),
@FLAG NVARCHAR(1),
@SEQ INT,
@CONTENT NVARCHAR(20),
-- 결과 담을 변수
@RESULT NVARCHAR(100),
@HDR_TEMP NVARCHAR(50),
@DTL_TEMP NVARCHAR(50)
-- 헤더의 커서 --------------------------------------
-- FOR SELET문 -> 한 줄씩 읽을 타겟 데이터를 SELECT함
DECLARE HDR_CURSOR CURSOR FOR
SELECT CODE, FLAG FROM #HDR
SELECT @RESULT = ''
-- 헤더 반복시작
OPEN HDR_CURSOR
-- FETCH문 : 한 줄 읽음
FETCH NEXT FROM HDR_CURSOR INTO @CODE, @FLAG -- SELET문에서 조회한 컬럼들과 동일하게 맞춰야함
-- @@FETCH_STATUS = 0 : FETCH문 수행됨
-- @@FETCH_STATUS = -1 : FETCH문 수행 실패
-- @@FETCH_STATUS = -2 : FETCH문 수행됐으나 행 없음
WHILE (@@FETCH_STATUS = 0) -- 한 줄 읽는거 성공 시 WHILE 반복
BEGIN
-- 헤더에 대해 다른 작업 진행
SELECT @HDR_TEMP = ''
SELECT @HDR_TEMP = @CODE + '(' + @FLAG + ') { '
-- 디테일 커서 선언
DECLARE DTL_CURSOR CURSOR FOR
SELECT SEQ, CONTENT FROM #DTL
WHERE CODE = @CODE -- 헤더의 PK로 조회함
-- 디테일 반복시작
OPEN DTL_CURSOR
SET @DTL_TEMP = ''
FETCH NEXT FROM DTL_CURSOR INTO @SEQ, @CONTENT
WHILE (@@FETCH_STATUS = 0)
BEGIN
-- 디테일에 대해 다른 작업 진행
SELECT @DTL_TEMP = @DTL_TEMP + @CODE + CAST(@SEQ AS VARCHAR) + '(' + @CONTENT + ') '
-- 디테일 다음 줄 읽음
FETCH NEXT FROM DTL_CURSOR INTO @SEQ, @CONTENT
END
-- 디테일 반복끝
CLOSE DTL_CURSOR -- 커서 닫기
DEALLOCATE DTL_CURSOR -- 커서 할당 해제
SELECT @RESULT = @RESULT + @HDR_TEMP + @DTL_TEMP + '} '
-- 헤더 다음 줄 읽음
FETCH NEXT FROM HDR_CURSOR INTO @CODE, @FLAG
END
-- 헤더 반복끝
CLOSE HDR_CURSOR
DEALLOCATE HDR_CURSOR
-- 임시 테이블 삭제
DROP TABLE #HDR
DROP TABLE #DTL
-- 결과 ----------------------------------------------
SELECT '실행순서 : ' + @RESULT
실행결과
![]() |
728x90
'DataBase > MSSQL' 카테고리의 다른 글
| [MSSQL] 조건에 따라 WHERE절 조건 바꾸기, 1=1 활용 (0) | 2022.09.21 |
|---|---|
| [MSSQL] ISNULL로 Empty, Null 체크 예시 (0) | 2022.09.21 |
| [MSSQL] 특정문자 포함여부에 따라 다른 값 출력(IF, CASE) (0) | 2022.04.29 |
| [MSSQL] 컬럼 합치기 STUFF + FOR XML PATH (0) | 2022.04.25 |
| [MSSQL] dbo.테이블 (0) | 2022.04.06 |

