PL/SQL でのカーソル用語に少し慣れていません。誰もこれを知っていますか?
16 に答える
暗黙カーソルは、問合せの実行時にOracleによって「自動的に」作成されるカーソルです。コーディングは簡単ですが、
- 非効率性 (ANSI 標準では、複数のレコードがあるかどうかを確認するために 2 回フェッチする必要があると規定されています)
- データ エラーに対する脆弱性 (2 つの行を取得すると、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;
明示カーソルは、宣言ブロックで次のように定義されます。
DECLARE
CURSOR cur IS
SELECT columns FROM table WHERE condition;
BEGIN
...
暗黙カーソルは、コード ブロックに直接実装されます。
...
BEGIN
SELECT columns INTO variables FROM table where condition;
END;
...
暗黙カーソルには匿名バッファ メモリが必要です。
明示カーソルは、その名前を使用して何度でも実行できます。明示カーソルは、無名のバッファ メモリに格納されるのではなく、ユーザー定義のメモリ空間に格納されるため、後で簡単にアクセスできます。
最初の質問への回答です。Oracleのドキュメントから直接
カーソルは、特定の SELECT または DML ステートメントの処理に関する情報を格納するプライベート SQL 領域へのポインターです。
明示カーソルは、次のように宣言するカーソルです。
CURSOR my_cursor IS
SELECT table_name FROM USER_TABLES
暗黙カーソルは、記述したインライン SQL (静的または動的) をサポートするために作成されたものです。
1.CURSOR: PLSQL が SQL ステートメントを発行すると、SQL ステートメントを解析および実行するためのプライベート作業領域が作成されます。これはカーソルと呼ばれます。
2.IMPLICIT: PL/SQL実行可能ブロックがSQL文を発行したとき。PL/SQL は暗黙的なカーソルを作成し、暗黙的なオープンとクローズが行われることを自動的に管理します。SQL ステートメントが 1 つの行のみを返す場合に使用されます。SQL%ROWCOUNT、SQL%FOUND、SQL%NOTFOUND、SQL%ISOPEN の 4 つの属性があります。
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;
最近では、暗黙カーソルは明示カーソルよりも効率的です。
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
明示カーソルを使用すると、データベース内の情報にアクセスする方法を完全に制御できます。いつカーソルをオープンするか、いつカーソルから (したがって、カーソルの SELECT ステートメント内のテーブルから) レコードをフェッチするか、フェッチするレコードの数、およびいつカーソルをクローズするかを決定します。カーソルの現在の状態に関する情報は、カーソル属性を調べることで入手できます。
詳細については、 http://www.unix.com.ua/orelly/oracle/prog2/ch06_03.htmを参照してください。
カーソルは、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 ... 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 つのレコードのみを返し、自動的に呼び出されます。ただし、明示カーソルは手動で呼び出され、複数のレコードを返す場合があります。
他の回答で述べたように、暗黙のカーソルは使いやすく、エラーが発生しにくいです。
また、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 から複数のテーブルを更新するための優れた回避策も提供します。
Oracle データベースによって実行されるすべての SQL ステートメントには、それに関連付けられたカーソルがあります。これは、処理情報を格納するためのプライベート作業領域です。暗黙カーソルは、すべての DML および SELECT ステートメントに対して、Oracle サーバーによって暗黙的に作成されます。
明示カーソルを宣言および使用してプライベート作業領域に名前を付け、プログラム ブロックに格納されている情報にアクセスできます。
明示的...
カーソル foo は select * from blah; です。オープン フェッチを開始 カーソルを閉じると終了 yada yada yada
それらを使用しないで、暗黙的に使用してください
カーソル foo は select * from blah; です。
for n in foo ループ x = n.some_column end ループ
私はあなたがこれを行うことができると思います
for n in (select * from blah) ループ...
暗黙に固執し、それらは自分自身を閉じ、より読みやすく、生活を楽にします。