SQLShack (한국어)

SQL Server 커서는 인터넷에서 공통적 인 주제 중 하나입니다. . 사용할 때와 사용하지 않을 때 다른 의견을 찾을 수 있습니다. 오늘 우리는 또한 그것들에 대해 이야기하고 그것들을 사용하지 않을 때 (안) 질문에 답할 것입니다.

데이터 모델과 일반적인 아이디어

이전 기사에서 Intro to SQL 서버 루프, SQL Server 루프에 대해 이야기했지만 데이터베이스의 데이터를 사용하지 않았습니다. 이상했지만 지금은 훨씬 더 명확 해져야합니다. 오늘은 커서에 대해 설명하면서 데이터베이스의 데이터를 사용하여 커서를 사용하지 않는시기를 보여 드리겠습니다. 우리가 사용할 데이터 모델은이 시리즈에서 사용하는 것과 동일합니다.

SQL Server는 3 개를 지원합니다. 다양한 커서 구현 – Transact-SQL 커서, API 커서 및 클라이언트 커서. 이 문서에서는 Transact-SQL 커서에 대해 중점적으로 설명합니다. DECLARE CURSOR 구문을 기반으로하기 때문에 쉽게 알아볼 수 있습니다.

SQL Server Cursor – 소개

코드와 예제로 이동하기 전에 SQL Server 커서가 무엇인지 설명해야합니다.

SQL Server 커서는 T-SQL 논리로, 관련 쿼리 결과를 반복 할 수 있습니다. 이를 통해 순차적으로 작업을 수행 할 수 있습니다. 예를 들어 단일 행에 대한 업데이트를 수행합니다.

때로는 이것이 도움이 될 수 있지만 데이터베이스로 작업 할 때는 절차 적 프로그래밍 패턴을 사용해서는 안됩니다. 오히려 선언적 프로그래밍을 고수하십시오. 주된 이유 중 하나는 DBMS가 이미 데이터 집합에 대한 작업을 수행하도록 최적화되어 있기 때문에 “시스템보다 똑똑”하려고하는 사람이되어서는 안됩니다.

그래도 좋습니다. 다른 것이 없다면 상속받은 코드에서 만나게 될 것이고 논리를 다시 작성해야 할 것입니다. 그리고 아무것도하기 전에 그것이 어떻게 작동하는지 이해해야합니다.

따라서 커서가 필요한 경우에 대해 알아야 할 사항은 다음과 같습니다.

  • 커서는 변수를 사용하여 루프의 각 부분에서 반환 된 값을 저장하므로 DECLARE가 필요합니다. 필요한 모든 변수
  • 다음으로 할 일은 DECLARE… CURSOR FOR SELECT 쿼리입니다. 여기서 커서를 선언하고 해당 커서와 관련된 쿼리도 정의합니다.
  • 커서를 열고 커서에서 NEXT FETCH
  • WHILE 루프에서 @@ FETCH_STATUS 변수 (WHILE @@ FETCH_STATUS = 0)를 테스트합니다. 조건이 유지되면 루프 BEGIN에 들어갑니다 … END 블록 및 해당 블록 내에서 명령문 수행
  • 전체 결과 집합을 반복 한 후 루프를 종료합니다. 커서를 닫고 할당 해제해야합니다. 할당 해제는 커서 정의를 삭제하고 사용 된 메모리를 해제하기 때문에 중요합니다.

SQL Server 커서 – 예

이제 두 개의 커서 예를 살펴 보겠습니다. 매우 간단하지만 커서가 작동하는 방식을 잘 설명합니다.

첫 번째 예에서는 모든 도시 ID와 이름을 관련 국가 이름과 함께 가져 오려고합니다. PRINT 명령을 사용하여 루프의 각 단계에서 조합을 인쇄합니다.

SQL Server 커서 및 while 루프는 우리가 예상했던대로 정확하게 반환했습니다. 모든 도시의 ID와 이름, 그리고 관련 국가는 데이터베이스에 있습니다.

여기서 언급해야 할 가장 중요한 것은이 결과 집합을 간단히 반환 할 수 있다는 것입니다. 커서의 DECLARE 부분에 저장된 원래 SQL 쿼리를 사용하므로 커서가 필요하지 않습니다.

한 가지 더 예를 들어 보겠습니다. 이번에는 정보 스키마 데이터베이스를 쿼리하여 테이블 이름으로 정렬 된 처음 5 개의 테이블을 반환합니다. 이러한 쿼리를 사용하는 것은별로 의미가 없지만이 예는 다음을 보여줍니다.

  • 정보 스키마 데이터베이스를 쿼리하는 방법
  • 몇 가지 명령 / 문을 결합하는 방법 이전 기사에서 언급했습니다 (IF… ELSE, WHILE 루프, CONCAT)

코딩 측면에서, 이번에는 루프에 아무것도 인쇄하지 않고 CONCAT을 사용하여 문자열을 생성했음을 강조하고 싶습니다. 또한 IF 문을 사용하여 첫 번째 패스에 있는지 테스트했으며 만약 그렇다면 “,”를 추가하지 않았습니다. 그렇지 않으면 문자열에 “,”를 추가합니다.

루프 후, 결과 문자열을 인쇄하고 커서를 닫고 할당을 해제했습니다.

STRING_AGG 함수를 사용하여이를 달성 할 수 있습니다. 이것은 SQL Server 2017부터 사용할 수 있으며 MySQL GROUP_CONCAT 함수와 동일합니다.

SQL Server Cursor – 언제 사용합니까?

시도해 보겠습니다. “SQL Server 커서를 사용해야 할 때와 사용하지 않을 때”라는 질문에 객관적인 대답을 제공하십시오. 시간 동안 상황이 바뀌고 커서를 “대체”하는 다른 개체에서 개선이 이루어 지므로이를 고려하십시오. 이 기사가 작성된 날짜.그럼 시작하겠습니다.

커서를 사용하면 안됩니다.

  • 거의 항상 🙂 어리석게 들릴 수 있지만 대부분의 경우에 해당합니다. SQL Server는 커서를 사용하여 해결하려는 작업을 정확히 수행하는 많은 수의 개체 & 함수를 구현합니다. 커서를 사용하기로 결정하기 전에 커서가 유일하게 가능한 (좋은) 솔루션이라는 결론을 내릴만큼 충분히 조사했는지 확인하십시오. 데이터베이스의 루프를 의미합니다. 이전 기사 인 SQL Server 루프 소개에서 루프를 사용했지만 데이터를 루프하지 않았습니다.

커서를 사용할 수 있습니다.

  • 대부분 백업, 무결성 검사, 색인 재 구축과 같은 데이터베이스 관리 작업에 사용됩니다.
  • 일회성 성능 저하 가능성이 전체 시스템 성능에 영향을 미치지 않는다고 확신하는 작업
  • 다른 매개 변수를 사용하여 저장 프로 시저를 몇 번 호출합니다. 이 경우 커서 변수에서 매개 변수를 가져와 루프 내부에서 호출합니다.

    저장 프로 시저 또는 커서 (또는 루프) 내부의 다른 쿼리를 호출하면 성능에 많은 영향을 미치기 때문입니다. 커서 루프, 처음부터 쿼리 / 프로 시저를 실행합니다. 그렇게하기로 결정했다면 가능한 결과를 알고 있어야합니다.

  • 이전 힌트는 커서를 사용해야 할 때 마지막 글 머리 기호를 알려줍니다. 작동 방식을 완전히 알고 있고 성능에 영향을주지 않는다고 확신하는 경우에는 사용해보십시오.

SQL Server Cursor – 사람들이 사용하지 않는 이유 ?

제가 대답하고 싶은 마지막 질문은 : 왜 커서를 사용하는 사람이 있습니까? 내가 보는 방식은 다음과 같습니다.

  • 일회성 작업이나 성과에 영향을주지 않는 정기적 인 작업에이를 사용하는 사람들에게는 변명이 있습니다. 그 이유 중 하나는 그러한 코드가 절차 적 코드이고, 익숙하다면 매우 가독성이 높기 때문입니다.
  • 반면에 데이터베이스에 대해 배우기 시작하고 절차 적 프로그래밍에 익숙한 사람들은 언급했듯이 커서를 사용하는 이유는 데이터베이스보다 절차 적 프로그래밍에 훨씬 더 가깝기 때문입니다. 이것은 그것들을 사용하는 이유가 아닙니다. 왜냐하면 여기서 유일한 변명은 당신이 작업을 수행하는 다른 (올바른) 방법을 모를 것이기 때문입니다.
  • 커서의 가장 중요한 점은 커서가 SQL 문과 비교할 때 속도가 느리므로 조만간 성능 문제로 이어질 수 있으므로 사용을 피해야합니다 (사용자가 수행하는 작업과 이유를 정확히 알 수없는 경우).

I 큰 기회가 있기 때문에 커서의 개념을 이해하는 것이 유용합니다. SQL Server에 몇 가지 새로운 옵션이 추가되기 전에는 인기가있었습니다. 또한 누군가를 사용하기 전에 누군가가 멈춘 곳에서 계속 작업해야 할 가능성이 있습니다. 커서 (프로 시저 코드)를 SQL (선언 코드)로 바꿔야 할 수도 있습니다.

결론

커서에 대한 더 나은 결론은 없습니다. – 사용하지 마십시오. 🙂 SQL Server는 이전에 선언적 코드를 사용하여 해결하기 어려웠던 문제를 해결하는 많은 변경 사항을 구현했습니다. 새로운 것을 조사하고 배우는 데 시간을 투자하고 마지막으로 최적의 코드를 생성하는 것이 좋습니다. 물론 그 이유를 알고 있고 그와 관련된 가능한 문제를 알고 있다면 사용할 수 있습니다.

목차

SQL 학습 : CREATE DATABASE & CREATE TABLE Operations

Learn SQL : INSERT INTO TABLE

Learn SQL : Primary Key

SQL 학습 : 외래 키

SQL 학습 : SELECT 문

SQL 학습 : INNER JOIN vs LEFT JOIN

SQL 학습 : SQL 스크립트

SQL 학습 : 관계 유형

SQL 학습 : 여러 테이블 결합

SQL 학습 : 집계 함수

SQL 학습 : 복잡한 SELECT 쿼리를 작성하는 방법?

SQL 학습 : INFORMATION_SCHEMA 데이터베이스

SQL 학습 : SQL 데이터 유형

SQL 학습 : 이론 설정

SQL 학습 : 사용자 정의 함수

SQL 학습 : 사용자 정의 저장 프로 시저

SQL 학습 : SQL보기

SQL 학습 : SQL 트리거

SQL 학습 : SQL 쿼리 연습

SQL 학습 : SQL 쿼리 예제

SQL 학습 : SQL 쿼리를 사용하여 수동으로 보고서 만들기

SQL 학습 : SQL Server 날짜 및 시간 함수

SQL 학습 : SQL Server 보고서 만들기 날짜 및 시간 함수 사용

SQL 학습 : SQL Server 피벗 테이블

SQL 학습 : Excel로 SQL Server 내보내기

SQL 학습 : SQL Server 루프 소개

SQL 학습 : SQL Server 커서

SQL 학습 : 데이터 삭제 및 업데이트를위한 SQL 모범 사례

SQL 학습 : 명명 규칙

SQL 학습 : SQL 관련 작업

SQL 학습 : SQL Server의 비동 등 조인

SQL 학습 : SQL 주입

  • 작성자
  • 최근 게시물
Emil은 데이터베이스 전문가입니다. 데이터베이스와 관련된 모든 분야에서 10 년 이상의 경험을 쌓았습니다. 수년 동안 그는 IT 및 금융 업계에서 일했으며 현재 프리랜서로 일하고 있습니다.
그의 과거 및 현재 업무는 데이터베이스 설계 및 코딩에서 데이터베이스에 대한 교육, 컨설팅 및 작성에 이르기까지 다양합니다. 또한 잊지 마세요, BI, 알고리즘 생성, 체스, philately, 개 2 개, 고양이 2 개, 아내 1 명, 아기 1 명 …
LinkedIn에서 찾을 수 있습니다.
Emil Drkusic의 모든 게시물보기

Emil Drkusic의 최신 게시물 (전체보기)
  • SQL 학습 : SQL 삽입-2020 년 11 월 2 일
  • SQL 학습 : SQL Server의 비동 등 조인-2020 년 9 월 29 일
  • SQL 학습 : SQL 관련 작업-2020 년 9 월 1 일

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다