SQL Server의 커서는 d입니다. 한 번에 각 행을 검색하고 해당 데이터를 조작할 수 있게 해주는 atabase 객체 . 커서는 행에 대한 포인터일 뿐입니다. 항상 SELECT 문과 함께 사용됩니다. 일반적으로 모음집입니다. SQL 미리 결정된 수의 행을 하나씩 반복하는 논리입니다. 커서의 간단한 예는 근로자 기록에 대한 광범위한 데이터베이스가 있고 세금과 휴가를 공제한 후 각 근로자의 급여를 계산하려는 경우입니다.
SQL 서버 커서의 목적은 데이터를 행 단위로 업데이트하거나, 변경하거나, 모든 레코드를 한 번에 검색할 때 불가능한 계산을 수행하는 것입니다. . 또한 SQL Server 데이터베이스 백업과 같은 관리 작업을 순차적으로 수행하는 데에도 유용합니다. 커서는 주로 개발, DBA, ETL 프로세스에서 사용됩니다.
이 문서에서는 커서 수명 주기, 커서가 사용되는 이유와 시기, 커서 구현 방법, 제한 사항, 커서 교체 방법 등 SQL Server 커서에 대한 모든 내용을 설명합니다.
커서의 수명주기
커서의 수명주기를 다음과 같이 설명할 수 있습니다. 다섯 개의 다른 섹션 다음과 같이:
1: 커서 선언
첫 번째 단계는 아래 SQL 문을 사용하여 커서를 선언하는 것입니다.
long에서 int로 자바
DECLARE cursor_name CURSOR FOR select_statement;
DECLARE 키워드 뒤에 CURSOR 데이터 유형으로 이름을 지정하여 커서를 선언할 수 있습니다. 그런 다음 커서의 출력을 정의하는 SELECT 문을 작성합니다.
2: 커서 열기
결과 집합에서 검색된 데이터를 저장하기 위해 커서를 여는 두 번째 단계입니다. 아래 SQL 문을 사용하여 이를 수행할 수 있습니다.
OPEN cursor_name;
3: 커서 가져오기
이는 커서에서 현재 활성 행에 대한 삽입, 업데이트 및 삭제 작업과 같은 데이터 조작을 수행하기 위해 행을 하나씩 또는 블록 단위로 가져올 수 있는 세 번째 단계입니다. 아래 SQL 문을 사용하여 이를 수행할 수 있습니다.
FETCH NEXT FROM cursor INTO variable_list;
우리는 또한 @@FETCHSTATUS 함수 SQL Server에서 커서에 대해 실행된 가장 최근 FETCH 문 커서의 상태를 가져옵니다. 그만큼 술책 @@FETCHSTATUS가 0 출력을 제공하면 문이 성공한 것입니다. 그만큼 하는 동안 문을 사용하여 커서에서 모든 레코드를 검색할 수 있습니다. 다음 코드는 이를 더 명확하게 설명합니다.
WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM cursor_name; END;
4: 커서 닫기
커서 작업을 마친 후 커서를 닫아야 하는 네 번째 단계입니다. 아래 SQL 문을 사용하여 이를 수행할 수 있습니다.
CLOSE cursor_name;
5: 커서 할당 해제
이는 커서 정의를 지우고 커서와 관련된 모든 시스템 리소스를 해제하는 다섯 번째이자 마지막 단계입니다. 아래 SQL 문을 사용하여 이를 수행할 수 있습니다.
DEALLOCATE cursor_name;
SQL Server 커서 사용
우리는 SQL Server를 포함한 관계형 데이터베이스 관리 시스템이 결과 집합이라는 행 집합의 데이터를 처리하는 데 탁월하다는 것을 알고 있습니다. 예를 들어 , 테이블이 있어요 product_table 제품 설명이 포함되어 있습니다. 우리가 업데이트하고 싶다면 가격 제품의 다음 아래 ' 업데이트' 쿼리는 '의 조건과 일치하는 모든 레코드를 업데이트합니다. 어디' 절:
UPDATE product_table SET unit_price = 100 WHERE product_id = 105;
때로는 애플리케이션이 단일 방식으로 행을 처리해야 하는 경우도 있습니다. 즉, 전체 결과 집합을 한 번에 처리하는 것이 아니라 행 단위로 처리해야 하는 경우도 있습니다. SQL Server의 커서를 사용하여 이 프로세스를 수행할 수 있습니다. 커서를 사용하기 전에 커서는 성능이 매우 나쁘다는 점을 알아야 하므로 항상 커서 외에는 옵션이 없는 경우에만 사용해야 합니다.
커서는 모든 프로그래밍 언어에서 한 번에 하나의 개체를 반복하기 위해 FOREACH, FOR, WHILE, DO WHILE과 같은 루프를 사용하는 것과 동일한 기술을 사용합니다. 따라서 프로그래밍 언어의 루핑 프로세스와 동일한 논리를 적용하므로 선택할 수 있습니다.
SQL Server의 커서 유형
다음은 아래에 나열된 SQL Server의 다양한 유형의 커서입니다.
- 정적 커서
- 동적 커서
- 앞으로 전용 커서
- 키셋 커서
정적 커서
정적 커서가 표시하는 결과 세트는 항상 커서를 처음 열었을 때와 동일합니다. 정적 커서는 결과를 다음 위치에 저장하므로 임시 DB , 그들은 항상 읽기 전용 . 정적 커서를 사용하여 앞뒤로 이동할 수 있습니다. 다른 커서와 달리 속도가 느리고 메모리를 더 많이 소비합니다. 결과적으로 스크롤이 필요한 경우에만 사용할 수 있고 다른 커서는 적합하지 않습니다.
이 커서는 데이터베이스가 열린 후 데이터베이스에서 제거된 행을 표시합니다. 정적 커서는 커서가 닫혔다가 다시 열리지 않는 한 INSERT, UPDATE 또는 DELETE 작업을 나타내지 않습니다.
동적 커서
동적 커서는 커서가 열려 있는 동안 데이터 업데이트, 삭제 및 삽입 작업을 수행할 수 있는 정적 커서와 반대입니다. 그것은 기본적으로 스크롤 가능 . 변경 사항이 커서 내부에서 발생하든 커서 외부에서 발생하든 상관없이 결과 집합의 행, 순서 및 값에 대한 모든 변경 사항을 감지할 수 있습니다. 커서 외부에서는 커밋될 때까지 업데이트를 볼 수 없습니다.
앞으로 전용 커서
모든 커서 중에서 기본이고 가장 빠른 커서 유형입니다. 정방향 전용 커서라고 합니다. 결과 세트를 통해서만 앞으로 이동합니다. . 이 커서는 스크롤을 지원하지 않습니다. 결과 집합의 처음부터 끝까지 행만 검색할 수 있습니다. 이를 통해 삽입, 업데이트 및 삭제 작업을 수행할 수 있습니다. 여기서 결과 집합의 행에 영향을 미치는 사용자의 삽입, 업데이트 및 삭제 작업의 효과는 커서에서 행을 가져올 때 표시됩니다. 행을 가져오면 커서를 통해 행에 대한 변경 사항을 볼 수 없습니다.
정방향 전용 커서는 세 가지 유형으로 분류됩니다.
- Forward_Only 키 세트
- Forward_Only 정적
- 빨리 감기
키셋 기반 커서
이 커서 기능 정적 커서와 동적 커서 사이에 위치 변화를 감지하는 능력에 대해. 정적 커서처럼 결과 집합의 구성원 및 순서에 대한 변경 사항을 항상 감지할 수는 없습니다. 동적 커서처럼 결과 집합 행 값의 변경 사항을 감지할 수 있습니다. 그것은 단지 첫 번째 행에서 마지막 행으로, 마지막 행에서 첫 번째 행으로 이동 . 이 커서가 열릴 때마다 순서와 구성원이 고정됩니다.
이는 키 세트의 키와 동일한 고유 식별자 세트로 작동됩니다. 키 세트는 커서가 처음 열렸을 때 SELECT 문을 정규화한 모든 행에 의해 결정됩니다. 또한 업데이트 및 삭제 작업을 지원하는 데이터 소스의 변경 사항을 감지할 수도 있습니다. 기본적으로 스크롤 가능합니다.
예제 구현
SQL 서버에서 커서 예제를 구현해 보겠습니다. 먼저 '라는 테이블을 생성하여 이를 수행할 수 있습니다. 고객 ' 아래 명령문을 사용합니다.
SQL의 다른 테이블에서 열을 선택하는 방법
CREATE TABLE customer ( id int PRIMARY KEY, c_name nvarchar(45) NOT NULL, email nvarchar(45) NOT NULL, city nvarchar(25) NOT NULL );
다음으로 테이블에 값을 삽입하겠습니다. 아래 명령문을 실행하여 테이블에 데이터를 추가할 수 있습니다.
INSERT INTO customer (id, c_name, email, city) VALUES (1,'Steffen', '[email protected]', 'Texas'), (2, 'Joseph', '[email protected]', 'Alaska'), (3, 'Peter', '[email protected]', 'California'), (4,'Donald', '[email protected]', 'New York'), (5, 'Kevin', '[email protected]', 'Florida'), (6, 'Marielia', '[email protected]', 'Arizona'), (7,'Antonio', '[email protected]', 'New York'), (8, 'Diego', '[email protected]', 'California');
우리는 다음을 실행하여 데이터를 확인할 수 있습니다. 선택하다 성명:
SELECT * FROM customer;
쿼리를 실행한 후 아래 출력을 볼 수 있습니다. 여덟 줄 테이블에 :
이제 고객 기록을 표시하는 커서를 만들어 보겠습니다. 아래 코드 조각은 모든 것을 하나로 묶어 커서 선언 또는 생성의 모든 단계를 설명합니다.
그리드 레이아웃
--Declare the variables for holding data. DECLARE @id INT, @c_name NVARCHAR(50), @city NVARCHAR(50) --Declare and set counter. DECLARE @Counter INT SET @Counter = 1 --Declare a cursor DECLARE PrintCustomers CURSOR FOR SELECT id, c_name, city FROM customer --Open cursor OPEN PrintCustomers --Fetch the record into the variables. FETCH NEXT FROM PrintCustomers INTO @id, @c_name, @city --LOOP UNTIL RECORDS ARE AVAILABLE. WHILE @@FETCH_STATUS = 0 BEGIN IF @Counter = 1 BEGIN PRINT 'id' + CHAR(9) + 'c_name' + CHAR(9) + CHAR(9) + 'city' PRINT '--------------------------' END --Print the current record PRINT CAST(@id AS NVARCHAR(10)) + CHAR(9) + @c_name + CHAR(9) + CHAR(9) + @city --Increment the counter variable SET @Counter = @Counter + 1 --Fetch the next record into the variables. FETCH NEXT FROM PrintCustomers INTO @id, @c_name, @city END --Close the cursor CLOSE PrintCustomers --Deallocate the cursor DEALLOCATE PrintCustomers
커서를 실행하면 다음과 같은 출력이 표시됩니다.
SQL Server 커서의 제한 사항
커서에는 몇 가지 제한 사항이 있으므로 커서 외에는 옵션이 없는 경우에만 항상 사용해야 합니다. 이러한 제한 사항은 다음과 같습니다.
- 커서는 레코드를 가져올 때마다 네트워크 왕복을 요구하여 네트워크 리소스를 소비합니다.
- 커서는 메모리에 상주하는 포인터 세트입니다. 즉, 다른 프로세스가 우리 컴퓨터에서 사용할 수 있는 일부 메모리가 필요하다는 의미입니다.
- 데이터를 처리할 때 테이블의 일부 또는 전체에 잠금을 적용합니다.
- 커서의 성능과 속도는 테이블 레코드를 한 번에 한 행씩 업데이트하기 때문에 느려집니다.
- 커서는 while 루프보다 빠르지만 오버헤드가 더 많습니다.
- 커서로 가져온 행과 열의 수는 커서 속도에 영향을 미치는 또 다른 측면입니다. 커서를 열고 fetch 문을 실행하는 데 걸리는 시간을 나타냅니다.
커서를 어떻게 피할 수 있나요?
커서의 주요 작업은 테이블을 행 단위로 탐색하는 것입니다. 커서를 피하는 가장 쉬운 방법은 다음과 같습니다.
SQL while 루프 사용
커서 사용을 피하는 가장 쉬운 방법은 임시 테이블에 결과 집합을 삽입할 수 있는 while 루프를 사용하는 것입니다.
사용자 정의 함수
때때로 커서는 결과 행 세트를 계산하는 데 사용됩니다. 요구 사항을 충족하는 사용자 정의 함수를 사용하여 이를 수행할 수 있습니다.
조인 사용
Join은 지정된 조건을 만족하는 열만 처리하므로 대용량 레코드를 처리해야 하는 경우 커서보다 빠른 성능을 제공하는 코드 줄을 줄입니다.