it-swarm-ko.tech

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

PL/SQL의 커서 링고에 약간 녹슬 었습니다. 누구든지 이것을 알고 있습니까?

25
Brian G

암시 적 커서는 Oracle이 쿼리를 실행할 때 "자동으로"생성 한 커서입니다. 코딩하는 것이 더 간단하지만

  • 비 효율성 (ANSI 표준은 두 개 이상의 레코드가 있는지 확인하기 위해 가져와야 함을 지정합니다)
  • 데이터 오류 취약성 (두 행이있는 경우 TOO_MANY_ROWS 예외 발생)

SELECT col INTO var FROM table WHERE something;

명시 적 커서는 자신이 만든 커서입니다. 더 많은 코드가 필요하지만 더 많은 제어 기능을 제공합니다. 예를 들어 첫 번째 레코드 만 원하고 다른 레코드가 있는지 신경 쓰지 않으면 open-fetch-close를 사용할 수 있습니다.

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

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

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

암시 적 커서는 코드 블록에 직접 영향을줍니다.

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

1. CURSOR : PLSQL이 SQL 문을 발행 할 때 SQL 문을 구문 분석 및 실행하기위한 개인 작업 영역을 작성하고이를 커서라고합니다.

2. IMPLICIT : PL/SQL 실행 블록이 sql 문을 실행할 때 PL/SQL은 암시 적 커서를 생성하고 자동으로 관리하여 즉시 열기 및 닫기가 발생 함을 의미합니다. sql 문이 하나의 행만 반환 할 때 사용되며 SQL % ROWCOUNT, SQL % FOUND, SQL % NOTFOUND, SQL % ISOPEN의 4 가지 특성이 있습니다.

3. EXPLICIT : 프로그래머가 만들고 관리합니다. 명시 적 열기, 가져 오기 및 닫기가 필요할 때마다 필요합니다. 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;
4
Ganesh Pathare

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

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

3
prince
3
pablo

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

CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

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

3
Dave Costa

첫 번째 질문에 대한 답. 오라클에서 직접 documentation

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

3
Ian Carpenter

명시 적 커서를 사용하면 데이터베이스의 정보에 액세스하는 방법을 완전히 제어 할 수 있습니다. 커서를 여는시기, 커서 (및 커서의 SELECT 문에있는 테이블 또는 테이블)에서 레코드를 페치 할시기 및 페치 할 레코드 수 및 커서를 닫을시기를 결정합니다. 커서의 현재 상태에 대한 정보는 커서 속성을 검사하여 사용할 수 있습니다.

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

2
Kristian

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

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

Explicit Cursors : 명시 적 커서는 컨텍스트 영역을보다 세밀하게 제어하기위한 프로그래머 정의 커서입니다. PL/SQL 블록의 선언 섹션에서 명시 적 커서를 정의해야합니다. 하나 이상의 행을 리턴하는 SELECT 문에서 작성됩니다.

명시 적 커서를 생성하는 구문은 다음과 같습니다.

CURSOR cursor_name IS select_statement; 
1
GOVIND DIXIT

커서는 Oracle 테이블의 SELECTed 창으로, 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 ... LOOP ... 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;
/

명시 적 커서에서 명시 적 방식으로 커서를 열고 닫아 레코드가 있는지 확인하고 종료 조건을 표시합니다.

1
UltraCommit

Google은 친구입니다 : http://docstore.mik.ua/orelly/Oracle/prog2/ch06_03.htm

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

명시 적 커서는 코드의 선언 섹션에 명시 적으로 정의되고 프로세스에서 이름이 지정된 SELECT 문입니다. UPDATE, DELETE 및 INSERT 문에 대한 명시 적 커서와 같은 것은 없습니다.

1
Derek Swingley

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

1
shaiksyedbasha

나는 이것이 오래된 질문이라는 것을 알고 있지만, 성능 관점에서 둘 사이의 차이점을 보여주기 위해 실용적인 예를 추가하는 것이 좋을 것이라고 생각합니다.

성능 관점에서 암시 적 커서가 더 빠릅니다.

둘 사이의 성능 차이를 보자.

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2    l_loops  NUMBER := 100000;
  3    l_dummy  dual.dummy%TYPE;
  4    l_start  NUMBER;
  5
  6    CURSOR c_dual IS
  7      SELECT dummy
  8      FROM   dual;
  9  BEGIN
 10    l_start := DBMS_UTILITY.get_time;
 11
 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
 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.

따라서 중요한 차이점이 분명하게 나타납니다.

더 많은 예 여기 .

1
Lalit Kumar B

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

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

0
ropable

다른 답변에서 언급했듯이 암시 적 커서는 사용하기 쉽고 오류가 적습니다.

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에 대한 다른 예 : PL/SQL FOR LOOP IMPLICIT CURSOR .

명시 적 형식보다 훨씬 짧습니다.

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

0
Vadzim