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ステートメントが1行のみを返す場合に使用します。4つの属性SQL%ROWCOUNT、SQL%FOUND、SQL%NOTFOUND、SQL%ISOPENがあります。
3.EXPLICIT:プログラマーによって作成および管理されます。明示的なオープン、フェッチ、クローズのたびに必要です。 sqlステートメントが複数の行を返す場合に使用されます。また、4つの属性CUR_NAME%ROWCOUNT、CUR_NAME%FOUND、CUR_NAME%NOTFOUND、CUR_NAME%ISOPENがあります。ループを使用して複数の行を処理します。プログラマーは、パラメーターを明示カーソルにも渡すことができます。
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(静的または動的)をサポートするために作成されます。
最初の質問への回答。 Oracleから直接 ドキュメント
カーソルは、特定のSELECTまたはDMLステートメントの処理に関する情報を格納するプライベートSQL領域へのポインターです。
明示カーソルを使用すると、データベース内の情報にアクセスする方法を完全に制御できます。カーソルを開くタイミング、カーソルから(したがってカーソルのSELECTステートメントのテーブルから)レコードをフェッチするタイミング、フェッチするレコード数、およびカーソルをクローズするタイミングを決定します。カーソルの現在の状態に関する情報は、カーソルの属性を調べることで入手できます。
詳細については、 http://www.unix.com.ua/orelly/Oracle/prog2/ch06_03.htm を参照してください。
PL/SQLでは、カーソルはこのコンテキスト領域へのポインタです。ステートメントの処理に必要なすべての情報が含まれています。
暗黙カーソル:暗黙カーソルは、SQLステートメントが実行されるたびに、ステートメントに明示カーソルがない場合、Oracleによって自動的に作成されます。プログラマは、暗黙カーソルとその中の情報を制御できません。
明示カーソル:明示カーソルは、コンテキスト領域をより詳細に制御するためのプログラマー定義のカーソルです。 PL/SQLブロックの宣言セクションで明示カーソルを定義する必要があります。複数の行を返すSELECTステートメントで作成されます。
明示カーソルを作成するための構文は次のとおりです。
CURSOR cursor_name IS select_statement;
カーソルは、OracleテーブルのSELECTウィンドウです。これは、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ステートメントの明示的なカーソルのようなものはありません。
暗黙カーソルは1つのレコードのみを返し、自動的に呼び出されます。ただし、明示カーソルは手動で呼び出され、複数のレコードを返すことができます。
これは古い質問ですが、パフォーマンスの観点から2つの違いを示す実用的な例を追加するとよいと思います。
パフォーマンスの観点から、暗黙カーソルはより高速です。
2つのパフォーマンスの違いを見てみましょう。
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倍高速であることを示しています。
誰もまだ言及していないのは奇妙です Impplicit 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から複数のテーブルを更新する に対する素晴らしい回避策も提供します。