PL/SQL의 커서 링고에 약간 녹슬 었습니다. 누구든지 이것을 알고 있습니까?
암시 적 커서는 Oracle이 쿼리를 실행할 때 "자동으로"생성 한 커서입니다. 코딩하는 것이 더 간단하지만
예
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;
명시 적 커서는 선언 블록에서 다음과 같이 정의됩니다.
DECLARE
CURSOR cur IS
SELECT columns FROM table WHERE condition;
BEGIN
...
암시 적 커서는 코드 블록에 직접 영향을줍니다.
...
BEGIN
SELECT columns INTO variables FROM table where condition;
END;
...
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;
암시 적 커서에는 익명 버퍼 메모리가 필요합니다.
명시 적 커서는 이름을 사용하여 반복해서 실행할 수 있으며 익명 버퍼 메모리에 저장되지 않고 사용자 정의 메모리 공간에 저장되므로 나중에 쉽게 액세스 할 수 있습니다.
명시 적 커서는 다음과 같이 선언 한 것입니다.
CURSOR my_cursor IS
SELECT table_name FROM USER_TABLES
암시 적 커서는 작성하는 인라인 SQL (정적 또는 동적)을 지원하기 위해 생성 된 커서입니다.
첫 번째 질문에 대한 답. 오라클에서 직접 documentation
커서는 특정 SELECT 또는 DML 문 처리에 대한 정보를 저장하는 개인용 SQL 영역에 대한 포인터입니다.
명시 적 커서를 사용하면 데이터베이스의 정보에 액세스하는 방법을 완전히 제어 할 수 있습니다. 커서를 여는시기, 커서 (및 커서의 SELECT 문에있는 테이블 또는 테이블)에서 레코드를 페치 할시기 및 페치 할 레코드 수 및 커서를 닫을시기를 결정합니다. 커서의 현재 상태에 대한 정보는 커서 속성을 검사하여 사용할 수 있습니다.
자세한 내용은 http://www.unix.com.ua/orelly/Oracle/prog2/ch06_03.htm 을 참조하십시오.
PL/SQL에서 커서는이 컨텍스트 영역에 대한 포인터입니다. 명령문 처리에 필요한 모든 정보가 들어 있습니다.
암시 적 커서 : 암시 적 커서는 명령문에 대한 명시 적 커서가 없을 때 SQL 문이 실행될 때마다 Oracle에 의해 자동으로 작성됩니다. 프로그래머는 암시 적 커서와 그 안에있는 정보를 제어 할 수 없습니다.
Explicit Cursors : 명시 적 커서는 컨텍스트 영역을보다 세밀하게 제어하기위한 프로그래머 정의 커서입니다. PL/SQL 블록의 선언 섹션에서 명시 적 커서를 정의해야합니다. 하나 이상의 행을 리턴하는 SELECT 문에서 작성됩니다.
명시 적 커서를 생성하는 구문은 다음과 같습니다.
CURSOR cursor_name IS select_statement;
커서는 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;
/
명시 적 커서에서 명시 적 방식으로 커서를 열고 닫아 레코드가 있는지 확인하고 종료 조건을 표시합니다.
Google은 친구입니다 : http://docstore.mik.ua/orelly/Oracle/prog2/ch06_03.htm
PL/SQL은 코드에서 명시 적 커서를 사용하지 않는 한 코드에서 직접 SQL 문을 실행할 때마다 암시 적 커서를 발행합니다. 개발자가 SQL 문에 대한 커서를 명시 적으로 선언하지 않기 때문에 "암시 적"커서라고합니다.
명시 적 커서는 코드의 선언 섹션에 명시 적으로 정의되고 프로세스에서 이름이 지정된 SELECT 문입니다. UPDATE, DELETE 및 INSERT 문에 대한 명시 적 커서와 같은 것은 없습니다.
암시 적 커서는 하나의 레코드 만 반환하며 자동으로 호출됩니다. 그러나 명시 적 커서는 수동으로 호출되며 둘 이상의 레코드를 리턴 할 수 있습니다.
나는 이것이 오래된 질문이라는 것을 알고 있지만, 성능 관점에서 둘 사이의 차이점을 보여주기 위해 실용적인 예를 추가하는 것이 좋을 것이라고 생각합니다.
성능 관점에서 암시 적 커서가 더 빠릅니다.
둘 사이의 성능 차이를 보자.
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.
따라서 중요한 차이점이 분명하게 나타납니다.
더 많은 예 여기 .
Oracle 데이터베이스에 의해 실행되는 모든 SQL 문에는 연관된 커서가 있으며 이는 처리 정보를 저장하는 개인 작업 영역입니다. 암시 적 커서는 모든 DML 및 SELECT 문에 대해 Oracle 서버에 의해 암시 적으로 생성됩니다.
명시 적 커서를 선언하고 사용하여 개인 작업 영역의 이름을 지정하고 프로그램 블록에서 저장된 정보에 액세스 할 수 있습니다.
다른 답변에서 언급했듯이 암시 적 커서는 사용하기 쉽고 오류가 적습니다.
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에서 여러 테이블 업데이트 에 대한 유용한 해결 방법을 제공합니다.