prosource

Oracle에서 명시적 커서와 암시적 커서의 차이점은 무엇입니까?

probook 2023. 6. 17. 09:28
반응형

Oracle에서 명시적 커서와 암시적 커서의 차이점은 무엇입니까?

저는 PL/SQL에서 제 커서 언어가 조금 녹슬었습니다.이거 아는 사람?

암시적 커서는 쿼리를 실행할 때 Oracle에 의해 "자동으로" 생성되는 커서입니다.코드화하는 것이 더 간단하지만 문제가 있습니다.

  • 비효율성(ANSI 표준은 레코드가 두 개 이상 있는지 확인하려면 두 번 가져와야 한다고 지정함)
  • 데이터 오류에 대한 취약성(두 개의 행이 있는 경우 TOO_MANY_ROWS 예외가 발생함)

SELECT col INTO var FROM table WHERE something;

명시적 커서는 사용자가 직접 만든 커서입니다.더 많은 코드가 필요하지만 더 많은 제어 권한을 부여합니다. 예를 들어, 첫 번째 레코드만 원할 경우 다른 레코드가 있는지 여부에 상관없이 그냥 열기-닫기만 할 수 있습니다.

DECLARE   
  CURSOR cur IS SELECT col FROM table WHERE something; 
BEGIN
  OPEN cur;
  FETCH cur INTO var;
  CLOSE cur;
END;

명시적 커서는 선언 블록에서 다음과 같이 정의됩니다.

DECLARE 
CURSOR cur IS 
  SELECT columns FROM table WHERE condition;
BEGIN
...

암시적 커서는 코드 블록에 직접 구현됩니다.

...
BEGIN
   SELECT columns INTO variables FROM table where condition;
END;
...

명시적 커서는 다음과 같이 선언하는 커서입니다.

CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

암시적 커서는 작성한 인라인 SQL(정적 또는 동적)을 지원하기 위해 생성된 커서입니다.

첫 번째 질문에 대한 답변입니다.Oracle 설명서에서 직접 확인 가능

커서는 특정 SELECT 또는 DML 문 처리에 대한 정보를 저장하는 개인 SQL 영역에 대한 포인터입니다.

1.커서:PLSQL이 sql 문을 실행할 때 sql 문을 구문 분석하고 실행할 개인 작업 영역을 만듭니다.

2. 암시:PL/SQL 실행 가능 블록이 sql 문을 실행하는 경우.PL/SQL은 암시적 커서를 생성하고 자동으로 관리함으로써 암시적으로 열기 및 닫기가 수행됨을 의미합니다.sql 문이 행을 하나만 반환할 때 사용됩니다.SQL%ROWCOUNT, SQL%FOUND, SQL%NOTFOUND, SQL%ISOPEN의 4가지 속성을 가집니다.

3.명시:프로그래머에 의해 생성되고 관리됩니다.명시적으로 열고, 가져오고, 닫을 때마다 필요합니다.sql 문이 두 개 이상의 행을 반환할 때 사용됩니다.또한 CUR_NAME%ROWCOUNT, CUR_NAME%FOUND, CUR_NAME%NOTFOUND, CUR_NAME%ISOPEN 4가지 속성을 가지고 있습니다.루프를 사용하여 여러 행을 처리합니다.프로그래머는 매개 변수를 명시적 커서로 전달할 수 있습니다.

  • 예: 명시적 커서

 

declare 
   cursor emp_cursor 
   is 
   select id,name,salary,dept_id 
   from employees; 
   v_id employees.id%type; 
   v_name employees.name%type; 
   v_salary employees.salary%type; 
   v_dept_id employees.dept_id%type; 
   begin 
   open emp_cursor; 
   loop 
   fetch emp_cursor into v_id,v_name,v_salary,v_dept_id; 
   exit when emp_cursor%notfound;
   dbms_output.put_line(v_id||', '||v_name||', '||v_salary||','||v_dept_id); 
   end loop;                    
   close emp_cursor; 
   end;

암시적 커서에는 익명 버퍼 메모리가 필요합니다.

명시적 커서는 이름을 사용하여 계속해서 실행할 수 있습니다.익명 버퍼 메모리에 저장되지 않고 사용자 정의 메모리 공간에 저장되므로 나중에 쉽게 액세스할 수 있습니다.

요즘은 명시적 커서보다 암시적 커서가 더 효율적입니다.

http://www.oracle.com/technology/oramag/oracle/04-sep/o54plsql.html

http://asktom.oracle.com/pls/asktom/f?p=100:11:0 ::::P11_QUESTION_ID:1205168148688

성능 측면에서 볼 때 암시적 커서가 더 빠릅니다.

명시적 커서와 암시적 커서 사이의 성능을 비교해 보겠습니다.

SQL> DECLARE
  2    l_loops  NUMBER := 100000;
  3    l_dummy  dual.dummy%TYPE;
  4    l_start  NUMBER;
  5    -- explicit cursor declaration
  6    CURSOR c_dual IS
  7      SELECT dummy
  8      FROM   dual;
  9  BEGIN
 10    l_start := DBMS_UTILITY.get_time;
 11    -- explicitly open, fetch and close the cursor
 12    FOR i IN 1 .. l_loops LOOP
 13      OPEN  c_dual;
 14      FETCH c_dual
 15      INTO  l_dummy;
 16      CLOSE c_dual;
 17    END LOOP;
 18
 19    DBMS_OUTPUT.put_line('Explicit: ' ||
 20                         (DBMS_UTILITY.get_time - l_start) || ' hsecs');
 21
 22    l_start := DBMS_UTILITY.get_time;
 23    -- implicit cursor for loop
 24    FOR i IN 1 .. l_loops LOOP
 25      SELECT dummy
 26      INTO   l_dummy
 27      FROM   dual;
 28    END LOOP;
 29
 30    DBMS_OUTPUT.put_line('Implicit: ' ||
 31                         (DBMS_UTILITY.get_time - l_start) || ' hsecs');
 32  END;
 33  /
Explicit: 332 hsecs
Implicit: 176 hsecs

PL/SQL procedure successfully completed.

따라서 상당한 차이가 분명히 보입니다.암시적 커서는 명시적 커서보다 훨씬 빠릅니다.

여기 더 많은 예가 있습니다.

명시적 커서를 사용하면 데이터베이스의 정보에 액세스하는 방법을 완벽하게 제어할 수 있습니다.커서를 열 시기, 커서에서 레코드를 가져올 시기(따라서 커서의 SELECT 문에 있는 테이블 또는 테이블에서), 가져올 레코드 수 및 커서를 닫을 시기를 결정합니다.커서의 현재 상태에 대한 정보는 커서 특성 검사를 통해 사용할 수 있습니다.

자세한 내용은 http://www.unix.com.ua/orelly/oracle/prog2/ch06_03.htm 을 참조하십시오.

Google은 여러분의 친구입니다: http://docstore.mik.ua/orelly/oracle/prog2/ch06_03.htm

코드가 명시적 커서를 사용하지 않는 한 PL/SQL은 코드에서 직접 SQL 문을 실행할 때마다 암시적 커서를 발급합니다.개발자는 SQL 문에 대한 커서를 명시적으로 선언하지 않으므로 "암묵적" 커서라고 합니다.

명시적 커서는 코드의 선언 섹션에 명시적으로 정의되고 프로세스에서 이름을 할당하는 SELECT 문입니다.UPDATE, DELETE 및 INSERT 문에는 명시적 커서가 없습니다.

커서는 Oracle 테이블에서 선택된 창으로, Oracle 테이블에 존재하는 레코드 그룹이며 특정 조건을 충족합니다.커서는 표의 모든 내용도 선택할 수 있습니다.커서를 사용하여 Oracle 열을 조작하여 결과에서 별칭을 지정할 수 있습니다.암시적 커서의 예는 다음과 같습니다.

BEGIN
   DECLARE
      CURSOR C1
      IS
         SELECT DROPPED_CALLS FROM ALARM_UMTS;

      C1_REC   C1%ROWTYPE;
   BEGIN
      FOR C1_REC IN C1
      LOOP
         DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
      END LOOP;
   END;
END;
/

FOR을 사용하는 경우...루프...END LOOP 커서의 레코드가 모두 분석되면 커서를 자동으로 열고 닫습니다.

명시적 커서의 예는 다음과 같습니다.

BEGIN
   DECLARE
      CURSOR C1
      IS
         SELECT DROPPED_CALLS FROM ALARM_UMTS;

      C1_REC   C1%ROWTYPE;
   BEGIN
      OPEN c1;

      LOOP
         FETCH c1 INTO c1_rec;

         EXIT WHEN c1%NOTFOUND;

         DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
      END LOOP;

      CLOSE c1;
   END;
END;
/

명시적 커서에서 명시적인 방법으로 커서를 열고 닫으면 레코드가 있는지 확인하고 종료 조건을 지정할 수 있습니다.

암시적 커서는 레코드를 하나만 반환하고 자동으로 호출됩니다.그러나 명시적 커서는 수동으로 호출되며 둘 이상의 레코드를 반환할 수 있습니다.

다른 답변에서 언급한 것처럼 암시적 커서는 사용하기 쉽고 오류 발생 가능성이 낮습니다.

그리고 암묵적 vs. Oracle PL/SQL의 명시적 커서는 암시적 커서가 명시적 커서보다 최대 2배 빠르다는 것을 보여줍니다.

아직 아무도 Implicit FOR LOOP Cursor에 대해 언급하지 않았다는 것이 이상합니다.

begin
  for cur in (
    select t.id from parent_trx pt inner join trx t on pt.nested_id = t.id
    where t.started_at > sysdate - 31 and t.finished_at is null and t.extended_code is null
  )
  loop
    update trx set finished_at=sysdate, extended_code = -1 where id = cur.id;
    update parent_trx set result_code = -1 where nested_id = cur.id;
  end loop cur;
end;

SO의 다른 예: LOOP INMILITE CURSOR에 대한 PL/SQL.

그것은 명시적인 형태보다 훨씬 더 짧습니다.

또한 CTE에서 여러 테이블을 업데이트하는 데도 유용한 해결 방법을 제공합니다.

PL/SQL에서 커서는 이 컨텍스트 영역에 대한 포인터입니다.문을 처리하는 데 필요한 모든 정보가 포함되어 있습니다.

암시적 커서:SQL 문이 실행될 때마다 해당 문에 대한 명시적 커서가 없을 때 Oracle에 의해 암시적 커서가 자동으로 생성됩니다.프로그래머는 암시적 커서와 그 안의 정보를 제어할 수 없습니다.

명시적 커서: 명시적 커서는 상황에 맞는 영역을 더 잘 제어할 수 있도록 프로그래머가 정의한 커서입니다.명시적 커서는 PL/SQL 블록의 선언 섹션에 정의되어야 합니다.둘 이상의 행을 반환하는 SELECT 문에 작성됩니다.

명시적 커서를 만드는 구문은 다음과 같습니다.

CURSOR cursor_name IS select_statement; 

Oracle 데이터베이스에서 실행되는 모든 SQL 문에는 처리 정보를 저장하는 개인 작업 영역인 관련 커서가 있습니다.암시적 커서는 모든 DML 및 SELECT 문에 대해 Oracle 서버에 의해 암시적으로 생성됩니다.

명시적 커서를 선언하고 사용하여 개인 작업 영역의 이름을 지정하고 프로그램 블록에 저장된 정보에 액세스할 수 있습니다.

명시적...

cursor foo는 blah에서 *를 선택했습니다. cursor yada yada를 닫을 때 fetch exit 열기 시작합니다.

그것들을 사용하지 말고 암시적으로 사용하세요.

커서 foo는 blah에서 *를 선택합니다;

n in foo 루프 x = n.some_column 엔드 루프의 경우

당신은 이것도 할 수 있을 것 같아요.

for nin (blah에서 * 선택) 루프...

암묵적으로 고수하고, 그들은 스스로 문을 닫고, 더 읽기 쉽고, 삶을 쉽게 만듭니다.

언급URL : https://stackoverflow.com/questions/74010/what-is-the-difference-between-explicit-and-implicit-cursors-in-oracle

반응형