1. 발생한 문제
사실 큰 문제는 아니다 O(∩_∩)O: 가끔 일괄 처리나 저장 프로시저에서 결과를 직접 선택하고 싶을 때가 있다. 레코드의 각 행을 하나씩 처리할 수 있는 데이터베이스 개체가 필요합니다.
2. 커서의 개념
위의 문제를 해결하기 위해 "커서"라는 데이터베이스 개체를 사용할 수 있습니다.
커서(Cursor)는 결과 집합을 순회하는 데 사용할 수 있는 데이터 유형으로 간주할 수 있으며, 포인터 또는 배열의 첨자와 동일합니다. 결과 집합을 처리하는 방법은 다음과 같습니다.
결과 집합에서 행 찾기
현재 결과 집합 위치에서 행 또는 행의 일부를 검색합니다.
결과 집합 대상 현재 행의 데이터 수정
3. 커서 사용 방법(생성, 열기, 읽기, 닫기, 삭제)
[커서 생성]
그리고 다양하게 정의합니다. 데이터형의 방식은 조금 비슷하지만 "@"을 붙이지 않도록 주의하세요. (사실 "커서"와 거의 똑같은 "커서형 변수"도 있고, @ 기호는 정의 시 사용됩니다.) 다음은 커서를 정의하는 문입니다.
선언 커서 이름 커서 [local|global] [forward_only|scroll]
for
select query 문
커서 로컬 커서와 글로벌 커서의 두 가지 유형으로 구분됩니다. 로컬은 로컬 커서를 나타내고 글로벌은 글로벌 커서를 나타냅니다(기본값, 생략 가능). Forward_only(기본값, 생략 가능)를 지정하면 커서가 정방향만 가능합니다. 즉, 행 사이를 앞뒤로 이동해야 하는 경우에는 레코드를 처음부터 끝까지만 추출할 수 있음을 의미합니다.
【커서 사용하기】
커서만 만들고 사용하지 않는 것은 의미가 없습니다. 커서를 만든 후 단계를 설명하기 위해 가장 간단한 예를 들어보겠습니다.
--[Create Cursor]
yiren에서 xingming을 선택하기 위해 C1 커서 선언
declare @xingming varchar (20)
--[커서 열기]
C1 열기
--[커서 읽기]
C1에서 다음 항목을 @xingming으로 가져오기 -- while의 특징은 한 번만 써야 한다는 것
while(@@FETCH_STATUS=0)
Begin
print 'Name:'+@ xingming
C1에서 @xingming으로 다음 가져오기
end
--[커서 닫기]
C1 닫기
--[ 커서 삭제】
C1 할당 취소
커서를 사용하는 방법이 Java의 whle(rs.next()){}와 매우 유사합니까? 실제로 rs.next()가 실행될 때 한 줄만 이동하십시오. 결과 집합에서 뒤로 이동합니다. 결과 집합의 끝에 도달하지 않으면 루프 본문이 계속 실행됩니다. 여기서 커서를 사용하는 경우에도 마찬가지입니다. @@FETCH_STATUS 값이 0이면 커서가 아직 끝에 도달하지 않은 것입니다. 더 이상 0이 아니면 커서가 끝에 도달하고 루프를 종료합니다.
커서 이름에서 변수 이름 목록으로 다음 항목을 가져오는 것은 커서 내용을 읽는 고정된 형태의 방법입니다. 쿼리 문이 여러 필드를 선택하는 경우 읽을 때 여러 변수에 값을 할당하려면 이 문장을 사용해야 합니다. 따라서 변수 이름 목록으로 작성하십시오.
【전역 커서 및 스크롤 커서】
앞서 언급한 전역 커서 및 스크롤 커서의 예는 다음과 같습니다.
if(CURSOR_STATUS('global','CURSOR_2' ) !=-3) CURSOR_2 할당 취소
CURSOR_2 커서 스크롤 선언 --전역 스크롤 커서
yiren에서 xingming,nicheng,xingbie 선택
--첫 번째 T- SQL 배치 시작
CURSOR_2 열기
@seq int 선언,
@xingming varchar(20),@nicheng varchar(50),@xingbie nchar
@seq=4로 설정
CURSOR_2에서 @xingming,@nicheng,@xingbie로 절대 @seq 가져오기
if (@@FETCH_STATUS=0)
start
print '+cast(@seq as varchar)+' 아티스트는 '+@xingming
@xingbie가 '남성'일 때 'him', '여성'일 때 'him', 그 다음 'she' 종료
+' 별명은 '+@nicheng
end
close CURSOR_2
go
- -두 번째 T-SQL 배치 시작
CURSOR_2 열기
@seq int 선언,
@xingming varchar(20),@nicheng varchar(50),@xingbie nchar
set @seq=5 -- 두 개의 배치로 나누어 @seq
를 다시 정의해야 합니다. 다시 CURSOR_2에서 @xingming,@nicheng,@xingbie
if(@@FETCH_STATUS로 절대 @seq를 가져옵니다. =0)
begin
print '+cast(@seq as varchar)+' 아티스트는 '+@xingming
'남성일 때 @xingbie'를 인쇄합니다. ' 그 다음 '그' 그 다음 '여자' 그 다음 '그녀' 끝
+의 닉네임은 '+@nicheng
끝
닫기 CURSOR_2
go
--세 번째 배치에서 커서 삭제
CURSOR_2 할당 해제
스크롤 옵션이 활성화되면 가져오기를 사용할 수 있습니다. 다음을 읽는 데 사용됩니다(뒤로 이동). 이전(앞으로 이동), 첫 번째(첫 번째 줄), 마지막(마지막 줄), 절대(절대 줄을 찾으려면 숫자 값을 사용), 상대(상대 줄을 배치하려면 숫자 값을 사용).
전역 커서는 한번 정의되면 항상 존재하므로 모든 배치에서 볼 수 있습니다. 할당 해제를 사용하여 제거하기 전까지는 사라지지 않습니다. CURSOR_STATUS('global','CURSOR_2') 로 상태를 확인할 수 있습니다.
【커서 중첩】
시스템 성능에 큰 영향을 미치므로 간단히 살펴보시기 바랍니다.
if(CURSOR_STATUS('global','CURSOR_3')!=-3) CURSOR_3 할당 해제
CURSOR_3 커서 선언
yanchu에서 yanchuid 선택
CURSOR_3 열기
@ycid int 선언
CURSOR_3
에서 @ycid로 다음 가져오기
while(@@FETCH_STATUS=0)
시작
print '+cast(@ycid as varchar)+' 공연에 참여하는 아티스트는 다음과 같습니다.'
CURSOR_4 커서를
선언합니다. select xingming from yiren where yirenid in
(select yirenid from yanchuyiren where yanchuid=@ycid)
--이 문장은 하위 쿼리를 사용하며 실제로 다른 커서를 중첩할 수 있습니다
선언 @ xingming varchar(50)
CURSOR_4 열기
CURSOR_4에서 @xingming으로 다음 항목 가져오기
while(@@FETCH_STATUS=0)
시작
@xingming 인쇄
CURSOR_4에서 @xingming으로 다음 가져오기
end
CURSOR_4 닫기
CURSOR_4 할당 해제
다음 가져오기 CURSOR_3
에서 @ycid로
print ''
end
CURSOR_3
할당 해제 CURSOR_3
[ 커서 변수]
커서 변수는 커서를 데이터형으로 실제로 사용하는 방법입니다. 커서 변수와 커서 개체의 차이점은 @가 있는지 여부입니다. 커서 변수를 생성할 때 먼저 @cursor 변수명 커서를 선언한 후, select 문에 @cursor 변수명=cursor를 설정합니다.
@c1 CURSOR 선언
yiren의 xingming 선택에 대해 @c1=cursor 설정
@c1 열기
@xingming varchar(50) 선언
@c1에서 @xingming으로 다음 항목 가져오기
print @xingming
close @c1
deallocate @c1
4. 커서에 대한 참고 사항 주의사항
【커서의 단점】
커서를 사용하면 결과 집합을 하나씩 꺼내어 처리하게 되므로 서버의 부담이 커진다. 게다가 커서 사용의 효율성도 높아진다. 기본 결과 집합을 사용하는 것보다 훨씬 낮습니다. 그러므로 커서를 사용할 수 없다면 사용하지 않는 것이 좋습니다.
[커서 추가 설명]
단지 커서를 열면 첫 번째 레코드를 가리키지 않고 첫 번째 레코드의 앞부분을 가리킵니다. 책을 비유로 들 수 있습니다. 커서는 기록 세트에 있는 기록(책 내용의 각 페이지)을 가리킬 수 있을 뿐만 아니라 기록 세트 외부에 기록이 없는 곳(표지와 뒷면)도 가리킬 수 있습니다. 책 표지).
@@fetch_status에는 세 가지 값이 있습니다. 0은 fetch가 정상적으로 실행됨을 의미하고, -1은 fetch가 결과 집합을 초과함을 의미하며, -2는 fetch가 가리키는 행이 더 이상 존재하지 않음을 의미합니다.
5. 커서를 사용하여 페이징 쿼리 저장 프로시저를 수정합니다.
첫 번째 분기를 다음 코드로 수정합니다.
if @currentpage >1
시작
if @currentpage>@totalpages
시작
set @currentpage = @totalpages
end
@start int 선언 , @count int
set @count = 0
set @start = @currentpage*@pagesize+1
set @sql='declarecursor_1 커서 스크롤 선택 * '
+@tablename+'에서 '+@idname
exec(@sql)
커서_1 열기
상대 @start,@pagesize 가져오기 순서 fromcursor_1
while @@fetch_status=0
begin
set @count = @count+1
cursor_1에서 다음 가져오기
if @count=@pagesize-1
break
end
커서_1 닫기
커서_1 할당 취소
end
그리고 원본 앞에 있는
exec(@sql)
을 제거하세요. 이 문장을 제거하지 않으면 저장 프로시저가 끝날 때 이 문장이 다시 실행되므로 실수로 @cursor_1 커서가 다시 생성됩니다.