DECLARE CURSOR(Transact-SQL)
스크롤 동작, 커서가 작동하는 결과 집합을 구축하는 데 사용되는 쿼리 등 Transact-SQL 서버 커서의 특성을 정의합니다. DECLARE CURSOR는 ISO 표준 기반의 구문과 Transact-SQL 확장 집합을 사용하는 구문을 모두 허용합니다.
ISO Syntax
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
[;]
Transact-SQL Extended Syntax
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
[;]
DECLARE CURSOR는 스크롤 동작, 커서가 작동하는 결과 집합을 만드는 데 사용되는 쿼리 등 Transact-SQL 서버 커서의 특성을 정의합니다. OPEN 문은 결과 집합을 채우고 FETCH는 결과 집합에서 행을 반환합니다. CLOSE 문은 커서와 연결된 현재 결과 집합을 해제하며 DEALLOCATE 문은 커서에서 사용된 리소스를 해제합니다.
DECLARE CURSOR 문의 첫 번째 형식은 커서 동작을 선언하기 위해 ISO 구문을 사용합니다. DECLARE CURSOR 문의 두 번째 형식은 ODBC 또는 ADO의 데이터베이스 API 커서 함수에서 사용된 것과 동일한 커서 형식을 사용하여 커서를 정의할 수 있는 Transact-SQL 확장을 사용합니다.
위의 두 가지 형식을 함께 사용할 수는 없습니다. CURSOR 키워드 앞에 SCROLL 또는 INSENSITIVE 키워드를 지정하면 CURSOR와 FOR select_statement 키워드 사이에 어떤 키워드도 사용할 수 없습니다. CURSOR와 FOR select_statement 키워드 사이에 키워드를 지정하면 CURSOR 키워드 앞에 SCROLL 또는 INSENSITIVE를 지정할 수 없습니다.
Transact-SQL 구문을 사용하는 DECLARE CURSOR에서 READ_ONLY, OPTIMISTIC, SCROLL_LOCKS를 지정하지 않을 경우 기본값은 다음과 같습니다.
-
권한 부족, 업데이트를 지원하지 않는 원격 테이블 액세스 등의 이유로 SELECT 문이 업데이트를 지원하지 않을 경우 커서는 READ_ONLY가 됩니다.
-
STATIC 및 FAST_FORWARD 커서는 기본적으로 READ_ONLY가 됩니다.
-
DYNAMIC 및 KEYSET 커서는 기본적으로 OPTIMISTIC이 됩니다.
커서 이름은 다른 Transact-SQL 문에서만 참조될 수 있으며 데이터베이스 API 함수에서는 참조될 수 없습니다. 예를 들어, 커서를 선언한 후 OLE DB, ODBC, ADO 함수나 메서드에서 커서 이름을 참조할 수 없습니다. 커서 행은 API의 인출 함수나 메서드를 사용하여 인출할 수 없고 Transact-SQL의 FETCH 문을 사용해야만 인출할 수 있습니다.
커서를 선언한 후 다음 시스템 저장 프로시저를 사용하여 커서의 특징을 확인할 수 있습니다.
|
시스템 저장 프로시저 |
설명 |
|---|---|
|
sp_cursor_list |
현재 연결에서 볼 수 있는 커서 목록과 그 특성을 반환합니다. |
|
sp_describe_cursor |
정방향 전용 커서, 스크롤 커서 등의 커서 특성을 설명합니다. |
|
sp_describe_cursor_columns |
커서 결과 집합에서 열의 특성을 설명합니다. |
|
sp_describe_cursor_tables |
커서에 의해 액세스되는 기본 테이블을 설명합니다. |
변수는 커서를 선언하는 select_statement의 일부로 사용될 수 있습니다. 커서가 선언된 후에는 커서 변수 값이 변경되지 않습니다. SQL Server 버전 6.5 및 이전 버전의 경우 커서를 다시 열 때마다 변수 값이 새로 고쳐집니다.
1. 단순 커서 및 구문 사용
다음 커서를 열 때 생성된 결과 집합에는 테이블에 있는 모든 행과 모든 열이 포함됩니다. 이 커서는 업데이트가 가능하며 이 커서에 대해 수행한 인출에는 모든 업데이트와 삭제 내용이 나타납니다. SCROLL 옵션을 지정하지 않았으므로 FETCHNEXT 인출만 사용할 수 있습니다.
DECLARE vend_cursor CURSOR FOR SELECT * FROM Purchasing.Vendor OPEN vend_cursor FETCH NEXT FROM vend_cursor
2. 중첩된 커서를 사용하여 보고서 출력 생성
다음 예에서는 커서를 중첩시켜 복잡한 보고서를 생성하는 방법을 보여 줍니다. 각 공급업체에 대해 내부 커서가 선언됩니다.
SET NOCOUNT ON DECLARE @vendor_id int, @vendor_name nvarchar(50), @message varchar(80), @product nvarchar(50) PRINT '-------- Vendor Products Report --------' DECLARE vendor_cursor CURSOR FOR SELECT VendorID, Name FROM Purchasing.Vendor WHERE PreferredVendorStatus = 1 ORDER BY VendorID OPEN vendor_cursor FETCH NEXT FROM vendor_cursor INTO @vendor_id, @vendor_name WHILE @@FETCH_STATUS = 0 BEGIN PRINT ' ' SELECT @message = '----- Products From Vendor: ' + @vendor_name PRINT @message -- Declare an inner cursor based -- on vendor_id from the outer cursor. DECLARE product_cursor CURSOR FOR SELECT v.Name FROM Purchasing.ProductVendor pv, Production.Product v WHERE pv.ProductID = v.ProductID AND pv.VendorID = @vendor_id -- Variable value from the outer cursor OPEN product_cursor FETCH NEXT FROM product_cursor INTO @product IF @@FETCH_STATUS <> 0 PRINT ' <<None>>' WHILE @@FETCH_STATUS = 0 BEGIN SELECT @message = ' ' + @product PRINT @message FETCH NEXT FROM product_cursor INTO @product END CLOSE product_cursor DEALLOCATE product_cursor -- Get the next vendor. FETCH NEXT FROM vendor_cursor INTO @vendor_id, @vendor_name END CLOSE vendor_cursor DEALLOCATE vendor_cursor
