오늘은 커서에 대해서 알아보도록 하겠습니다. 어떤 리스트에서 루프로 돌리면서 한 루프에 몇 가지 데이터를 저장하여 사용할 때 커서가 많이 쓰입니다. SQL (시퀄)에서는 테이블을 불러와서 각 Row 당 처리를 하는 방법이 많지는 않아서 커서가 대표적으로 쓰이죠. 하지만 커서는 서버의 리소스를 이용하는 기능이라 잘못 이용하다가는 서버 과부하가 되니 꼭 알아둬야 할 몇 가지가 있습니다.
왜 이름이 커서가 됐을까요. 영어로는 커서라는 뜻이 어떤 곳을 지정하는 물체 정도의 뜻이 되거든요. 그래서 데이터중 어떤 곳의 위치를 지정한다는 뜻으로 이 단어가 쓰이는 것입니다. 마우스의 커서도 그 뜻이 있지요.
아래의 코드로 설명드릴게요
우선 커서와 루프에 이용될 변수들을 지정합니다
-- 변수 지정
DECLARE @city_name VARCHAR(128);
DECLARE @country_name VARCHAR(128);
DECLARE @city_id INT;
-- 커서 지정
DECLARE cursor_city_country CURSOR FOR
SELECT city.id, TRIM(city.city_name), TRIM(country.country_name)
FROM city
INNER JOIN country ON city.country_id = country.id;
지정된 커서를 아래와 같이 오픈합니다
-- 커서 오픈
OPEN cursor_city_country;
루프 구동전에 아래같이 FETCH라는 커맨드로 커서를 이용하여 변수에 데이터를 넣습니다.
FETCH NEXT FROM cursor_city_country INTO @city_id, @city_name, @country_name;
그리고 루프를 구동합니다. @@FETCH_STATUS 변수는 커서에 데이터가 없으면 0이라는 값이 리턴이 되므로 루프의 컨디션을 WHILE @@FETH_STATUS = 0로 넣는 거죠. 그러면 루프가 끝나는 시기는 커서에 지정된 값이 없을 때죠. 그리고 루프 마지막에 다시 FETCH를 써서 계속 값을 지정시킵니다. 테이블 마지막이 지나면 자동적으로 값이 지정이 되지 않습니다.
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT CONCAT('city id: ', @city_id, ' / city name: ', @city_name, ' / country name: ', @country_name);
FETCH NEXT FROM cursor_city_country INTO @city_id, @city_name, @country_name;
END;
마지막으로 쓰고 있는 서버 리소스를 커서를 닫으면서 다시 돌려놓습니다. 이 부분이 아주 중요합니다. CLOSE와 DEALLOCATE둘다 쓰셔야 하죠. 오픈된 커서를 닫고 (Close), Allocate 된 서버의 리소스를 Deallocate 한다는 커맨드입니다. 이걸 안 쓰면 커서에 쓰이던 메모리가 계속 이 커서에 축적이 되어서 나중엔 크래시가 되는 거죠.
-- 커서 닫기
CLOSE cursor_city_country;
DEALLOCATE cursor_city_country;
아래가 완전체 코드 블록입니다.
-- 변수 지정
DECLARE @city_name VARCHAR(128);
DECLARE @country_name VARCHAR(128);
DECLARE @city_id INT;
-- 커서 지정
DECLARE cursor_city_country CURSOR FOR
SELECT city.id, TRIM(city.city_name), TRIM(country.country_name)
FROM city
INNER JOIN country ON city.country_id = country.id;
-- 커서 오픈
OPEN cursor_city_country;
-- 커서를 이용한 루프
FETCH NEXT FROM cursor_city_country INTO @city_id, @city_name, @country_name;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT CONCAT('city id: ', @city_id, ' / city name: ', @city_name, ' / country name: ', @country_name);
FETCH NEXT FROM cursor_city_country INTO @city_id, @city_name, @country_name;
END;
-- 커서 닫기
CLOSE cursor_city_country;
DEALLOCATE cursor_city_country;
수고하셨습니다. 즐거운 코딩되세요!
도움이 되셨거나 즐거우셨다면 아래의 ❤️공감버튼이나 구독버튼을 눌러 주세요~ 감사합니다
Visual Studio 인스톨러 다운로드 속도 개선법 (0) | 2023.03.24 |
---|---|
API 와 마이크로서비스 (Microservices) 의 다른 점은? (0) | 2023.03.22 |
100% 모든 환경에 작동하는 페이지 이동 이벤트 포착 자바스크립트 코드 - JavaScript (0) | 2023.03.13 |
Entity Framework Core - Entity Change (엔티티 체인지 하기) - C# & .NET (0) | 2023.03.06 |
this... Static Method (this 정적 메소드) - C# & .NET (0) | 2023.02.20 |