커서(cursor)란?
- 데이터베이스에서 한 번에 한 행씩 처리하는 데 사용되는 기능입니다. 일반적으로 커서는 단일 행이나 다중 행 데이터에 접근하고 처리해야 할 때 유용합니다.
- 커서는 선언, 열기, 데이터읽기, 닫기, 할당해제 등의 단계로 나뉜다.
1. 선언(DECLARE):
- 커서를 선언하기 위해 DECLARE CURSOR 문을 사용합니다. 이 단계에서는 커서의 이름, 커서 속성 및 커서와 연관된 SELECT 문을 정의합니다. 커서에 필요한 컬럼들을 선택하고, WHERE 절과 JOIN 절을 사용하여 데이터를 필터링하거나 조인할 수 있습니다.
DECLARE cur CURSOR FOR
SELECT Column1, Column2
FROM Table
WHERE Condition;
2. 열기(OPEN):
- OPEN 문을 사용하여 선언된 커서를 엽니다. 커서를 열면 커서가 데이터를 읽을 준비가 되고, 첫 번째 행을 가리키게 됩니다.
OPEN cur;
3. 데이터읽기(FETCH):
- FETCH 문을 사용하여 커서에서 한 번에 한 행씩 데이터를 읽습니다. FETCH NEXT 문은 다음 행을 가져오고, FETCH PRIOR 문은 이전 행을 가져옵니다. 읽은 데이터는 커서의 변수에 할당됩니다.
- 이 단계는 반복문과 함께 사용하여 커서를 통해 데이터를 순차적으로 처리하는 데 사용됩니다.
FETCH NEXT FROM cur INTO @var1 @var2 ...
- FETCH, FETCH_STATUS 좀 더 자세히 => https://fehoon.tistory.com/232
4. 닫기(CLOSE):
- CLOSE 문을 사용하여 커서를 닫습니다. 커서가 닫히면 더 이상 데이터를 읽을 수 없습니다. 단순히 커서를 닫기 위해서만 사용되는 것이며, 메모리나 자원은 아직 할당 상태입니다.
CLOSE cur;
5. 할당 해제(Deallocate):
- DEALLOCATE 문을 사용하여 커서와 관련된 메모리 및 자원을 할당 해제합니다. 커서를 더 이상 사용하지 않을 때 호출되며, 메모리와 자원을 반환합니다.
DELLOCATE cur;
- 예시
- 주문 날짜(OrderDate) 범위를 입력받아 해당 기간 동안의 주문 상품 수량을 계산하는 커서를 사용하는 예.
Order 테이블:
OrderID (주문 ID)
CustomerID (고객 ID)
OrderDate (주문 날짜)
OrderItem 테이블:
OrderItemID (주문 상품 ID)
OrderID (주문 ID)
ProductID (상품 ID)
Quantity (수량)
DECLARE @startDate DATE, @endDate DATE, @totalQuantity INT
SET @startDate = '2023-01-01'
SET @endDate = '2023-03-31'
SET @totalQuantity = 0
DECLARE @itemQuantity INT
DECLARE cur CURSOR FOR
SELECT oi.Quantity
FROM OrderItem oi
INNER JOIN [Order] o ON oi.OrderID = o.OrderID
WHERE o.OrderDate BETWEEN @startDate AND @endDate
OPEN cur
FETCH NEXT FROM cur INTO @itemQuantity
WHILE @@FETCH_STATUS = 0
BEGIN
SET @totalQuantity = @totalQuantity + @itemQuantity
FETCH NEXT FROM cur INTO @itemQuantity
END
CLOSE cur
DEALLOCATE cur
PRINT '총 수량: ' + CAST(@totalQuantity AS VARCHAR)
- 업데이트 커서 예시
DECLARE @id INT, @newSalary DECIMAL(10, 2)
DECLARE cur CURSOR FOR
SELECT Id, Salary FROM Employees WHERE Department = 'Finance'
OPEN cur
FETCH NEXT FROM cur INTO @id, @newSalary
WHILE @@FETCH_STATUS = 0
BEGIN
-- 행 업데이트
UPDATE Employees SET Salary = @newSalary * 1.1 WHERE Id = @id
FETCH NEXT FROM cur INTO @id, @newSalary
END
CLOSE cur
DEALLOCATE cur
- 커서(cursor)와 함수(function)은 지양해야 한다.
- 커서나 함수를 사용해보면 알겠지만 처리속도가 매우 느린편이다.
- 일반적으로 SQL Server에서는 커서(cursor)와 함수(function)의 사용을 가능한 한 지양하는 것이 좋습니다. 이는 성능 및 유지보수 관점에서 권장되는 접근 방법입니다. 그러나 상황에 따라서는 커서와 함수를 사용해야 할 수도 있습니다.
- 커서는 데이터베이스에서 데이터를 한 번에 한 행씩 처리하는 데 사용됩니다. 커서를 사용하면 반복적인 작업을 수행할 수는 있지만, 대량의 데이터에 대해 처리할 경우 성능 문제가 발생할 수 있습니다. 커서는 행 단위로 작업하기 때문에 대량의 데이터를 처리하는 경우에는 집합 기반(set-based) 작업에 비해 더 많은 시간과 자원을 요구할 수 있습니다. 따라서 커서 대신 집합 기반의 SQL 구문을 사용하는 것이 일반적으로 성능상 유리합니다.
- 함수는 코드의 재사용성과 모듈화를 위해 사용됩니다. 하지만 SQL Server에서 사용자 정의 함수(user-defined function)를 사용할 경우 성능 문제가 발생할 수 있습니다. 함수는 행 단위로 작업하며, 함수를 사용하는 쿼리는 함수의 호출 횟수에 따라 성능이 저하될 수 있습니다. 함수를 사용하는 쿼리는 실행 계획을 최적화하기 어렵기 때문에 성능 문제가 발생할 수 있습니다. 대신에 인라인 테이블 함수(inline table-valued function)나 조인 등을 사용하여 집합 기반의 SQL 구문으로 작성하는 것이 성능상 유리합니다.
반응형
'DATABASE > MsSQL' 카테고리의 다른 글
SQL Server 테이블 복제 방법(레코드 포함/미포함) (0) | 2023.07.23 |
---|---|
FETCH, @@FETCH_STATUS 종류 (0) | 2023.07.08 |
[Stored Procedure] 매개변수 전달 및 출력 (0) | 2023.07.01 |
[SQL Server_제어 흐름] 7. RETURN 문 사용방법 (0) | 2023.06.25 |
[SQL Server_제어 흐름] 6. GOTO LABLE 사용방법 (0) | 2023.06.25 |
[SQL Server_제어 흐름] 5. WAIT FOR 사용 방법 (0) | 2023.06.25 |
[SQL Server_제어 흐름] 4. WHILE 루프 사용 방법 (0) | 2023.06.25 |
[SQL Server_제어 흐름] 3. IF 문 사용 방법 (0) | 2023.06.25 |