Oracle PL/SQL 커서: 암시적, 명시적, For 루프(예 포함)
PL/SQL의 CURSOR란 무엇입니까?
커서는 이 컨텍스트 영역에 대한 포인터입니다. Oracle 명령문에 대한 모든 정보를 포함하는 SQL 문을 처리하기 위한 컨텍스트 영역을 생성합니다.
PL/SQL을 사용하면 프로그래머는 커서를 통해 컨텍스트 영역을 제어할 수 있습니다. 커서는 SQL 문에서 반환된 행을 보유합니다. 커서가 보유하는 행 세트를 활성 세트라고 합니다. 이러한 커서는 코드의 다른 위치에서 참조할 수 있도록 이름을 지정할 수도 있습니다.
커서는 두 가지 유형이 있습니다.
- 암시적 커서
- 명시적 커서
암시적 커서
데이터베이스에서 DML 작업이 발생할 때마다 해당 작업에서 영향을 받는 행을 보관하는 암묵적 커서가 생성됩니다. 이러한 커서는 이름을 지정할 수 없으므로 코드의 다른 위치에서 제어하거나 참조할 수 없습니다. 커서 속성을 통해 가장 최근의 커서만 참조할 수 있습니다.
명시적 커서
프로그래머는 DML 작업을 실행하기 위해 명명된 컨텍스트 영역을 만들어 더 많은 제어를 얻을 수 있습니다. 명시적 커서는 선언 섹션에서 정의되어야 합니다. PL/SQL 블록, 코드에서 사용해야 하는 'SELECT' 문에 대해 생성됩니다.
다음은 명시적 커서 작업과 관련된 단계입니다.
- 커서 선언 커서를 선언한다는 것은 단순히 선언 부분에 정의된 'SELECT' 문에 대해 하나의 명명된 컨텍스트 영역을 만드는 것을 의미합니다. 이 컨텍스트 영역의 이름은 커서 이름과 동일합니다.
- 열기 커서커서를 열면 다음과 같이 지시됩니다. PL / SQL 이 커서에 대한 메모리를 할당합니다. 그러면 커서가 레코드를 가져올 준비가 됩니다.
- 커서에서 데이터 가져오기이 과정에서 'SELECT' 문이 실행되고, 가져온 행이 할당된 메모리에 저장됩니다. 이제 이러한 세트를 활성 세트라고 합니다. 커서에서 데이터를 가져오는 것은 레코드 수준 활동이므로 레코드별로 데이터에 액세스할 수 있습니다. 각 fetch 문은 하나의 활성 세트를 가져오고 해당 특정 레코드의 정보를 보유합니다. 이 명령문은 레코드를 가져와서 'INTO' 절의 변수에 할당하는 'SELECT' 명령문과 동일하지만 예외가 발생하지 않습니다.
- 커서 닫기이제 모든 레코드를 가져온 후에는 이 컨텍스트 영역에 할당된 메모리가 해제되도록 커서를 닫아야 합니다.
통사론
DECLARE CURSOR <cursor_name> IS <SELECT statement^> <cursor_variable declaration> BEGIN OPEN <cursor_name>; FETCH <cursor_name> INTO <cursor_variable>; . . CLOSE <cursor_name>; END;
- 위 구문에서 선언 부분에는 커서 선언과 가져온 데이터를 할당할 커서 변수가 포함됩니다.
- 커서 선언에 지정된 'SELECT' 문에 대해 커서가 생성됩니다.
- 실행 부분에서는 선언된 커서를 열고, 가져오고, 닫습니다.
커서 속성
암시적 커서와 명시적 커서는 모두 액세스할 수 있는 특정 속성을 가지고 있습니다. 이러한 속성은 커서 작업에 대한 자세한 정보를 제공합니다. 아래는 다양한 커서 속성과 그 사용법입니다.
커서 속성 | 상품 설명 |
---|---|
%녹이다 | 가장 최근의 페치 작업에서 레코드를 성공적으로 페치했으면 'TRUE'라는 부울 결과가 반환되고, 그렇지 않으면 FALSE가 반환됩니다. |
% NOTFOUND | 이것은 %FOUND와 반대로 작동합니다. 가장 최근의 페치 작업에서 레코드를 페치하지 못한 경우 'TRUE'를 반환합니다. |
% ISOPEN | 주어진 커서가 이미 열려 있으면 부울 결과 'TRUE'를 반환하고, 그렇지 않으면 'FALSE'를 반환합니다. |
% ROWCOUNT % | 숫자 값을 반환합니다. DML 활동의 영향을 받은 실제 레코드 수를 제공합니다. |
명시적 커서 예:
이 예에서는 명시적 커서를 선언하고, 열고, 가져오고, 닫는 방법을 살펴보겠습니다.
커서를 사용하여 emp 테이블에서 모든 직원의 이름을 투영합니다. 또한 커서 속성을 사용하여 커서에서 모든 레코드를 가져오도록 루프를 설정합니다.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; lv_emp_name emp.emp_name%type; BEGIN OPEN guru99_det; LOOP FETCH guru99_det INTO lv_emp_name; IF guru99_det%NOTFOUND THEN EXIT; END IF; Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name); END LOOP; Dbms_output.put_line(‘Total rows fetched is‘||guru99_det%R0WCOUNT); CLOSE guru99_det; END: /
산출
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Total rows fetched is 3
코드 설명
- 코드 라인 2: 'SELECT emp_name FROM emp' 명령문에 대해 커서 guru99_det를 선언합니다.
- 코드 라인 3: 변수 lv_emp_name을 선언합니다.
- 코드 라인 5: 커서 guru99_det를 엽니다.
- 코드 라인 6: 'emp' 테이블의 모든 레코드를 가져오도록 기본 루프 문을 설정합니다.
- 코드 라인 7: guru99_det 데이터를 가져오고 lv_emp_name에 값을 할당합니다.
- 코드 라인 9: 커서 속성 '%NOTFOUND'를 사용하여 커서에 있는 모든 레코드를 가져왔는지 확인합니다. 가져오면 'TRUE'를 반환하고 제어는 루프에서 종료됩니다. 그렇지 않으면 제어는 커서에서 데이터를 계속 가져와 데이터를 인쇄합니다.
- 코드 라인 11: 루프 문의 EXIT 조건입니다.
- 코드 라인 12: 가져온 직원 이름을 인쇄합니다.
- 코드 라인 14: 커서 속성 '%ROWCOUNT'를 사용하여 커서에서 영향을 받거나 가져온 총 레코드 수를 찾습니다.
- 코드 라인 15: 루프를 종료한 후 커서가 닫히고 할당된 메모리가 해제됩니다.
FOR 루프 커서 문
커서 작업에는 "FOR LOOP" 문을 사용할 수 있습니다. FOR 루프 문에서 범위 제한 대신 커서 이름을 지정하여 루프가 커서의 첫 번째 레코드부터 커서의 마지막 레코드까지 작동하도록 할 수 있습니다. 커서 변수, 커서 열기, 커서 가져오기 및 닫기는 FOR 루프에 의해 암시적으로 수행됩니다.
통사론
DECLARE CURSOR <cursor_name> IS <SELECT statement>; BEGIN FOR I IN <cursor_name> LOOP . . END LOOP; END;
- 위 구문에서 선언 부분에는 커서 선언이 포함됩니다.
- 커서 선언에 지정된 'SELECT' 문에 대해 커서가 생성됩니다.
- 실행 부분에서는 선언된 커서가 FOR 루프에 설정되며 이 경우 루프 변수 'I'가 커서 변수로 동작합니다.
Oracle 루프 예제에 대한 커서:
이 예에서는 커서-FOR 루프를 사용하여 emp 테이블에서 모든 직원 이름을 투영합니다.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; BEGIN FOR lv_emp_name IN guru99_det LOOP Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name.emp_name); END LOOP; END; /
산출
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY
코드 설명
- 코드 라인 2: 'SELECT emp_name FROM emp' 명령문에 대해 커서 guru99_det를 선언합니다.
- 코드 라인 4: 루프 변수 lv_emp_name을 사용하여 커서에 대한 'FOR' 루프를 구성합니다.
- 코드 라인 5: 루프가 반복될 때마다 직원 이름을 인쇄합니다.
- 코드 라인 8: 루프 종료
참고 : Cursor-FOR 루프에서는 커서 열기, 가져오기 및 닫기가 암시적으로 수행되므로 커서 속성을 사용할 수 없습니다. FOR 루프.