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 테이블에서 모든 직원의 이름을 투영합니다. 또한 커서 속성을 사용하여 커서에서 모든 레코드를 가져오도록 루프를 설정합니다.

Oracle PL/SQL 커서

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 루프.