PL/SQL スクリプトで MERGE DML ステートメントを使用しているときに、PL/SQL で更新された行数と挿入された行数の情報を受け取る方法があるかどうかを知りたいです。
ここで説明されているマージの Oracle の例を使用してみましょう: MERGE の例
この機能は関数で使用されていますが、更新された行数と挿入された行数の情報もログに記録したいと考えています。
挿入数と更新数を別々に取得する組み込みの方法はありません。SQL%ROWCOUNT
おそらくすでにご存知のように、マージされた行数がわかりますが、挿入と更新の個別の値を取得するのに相当するものはありません。
Adrian Billington によるこの記事では、マージに関数呼び出しを含めることで情報を取得する方法を示していますが、これによりオーバーヘッドが少し増える可能性があります。
同様の、おそらくもっと単純なトリックが Oracle フォーラムに MichaelS からあります。ここで再現したくなりますが、それが許可されているかどうかはわかりませんが、基本的にはsys_context
、エイドリアンのソリューションがパッケージ変数で行ったのとほぼ同じ方法で、カウントを維持するために使用しています. よりクリーンで、フォローとメンテナンスが簡単だと思うので、私はそれを使用します。
まだリンクのみの回答に危険なほど近いですが、他の人の作品を盗用したくありません...
@AlexPooleが指摘した回避策は機能しますが、トリガーを使用したより自然な方法で更新、挿入、さらには可能な削除をカウントしないのは奇妙です。
簡単なテストテーブルがあるとします:
create table test_table (id number, col number)
カウンターの簡易パッケージを定義する
create or replace package pkg_test_table_counter as
procedure reset_counter;
procedure count_insert;
procedure count_update;
procedure count_delete;
function get_insert_count return number;
function get_update_count return number;
function get_delete_count return number;
end;
...およびパッケージ本体:
create or replace package body pkg_test_table_counter as
vUpdateCount number := 0;
vInsertCount number := 0;
vDeleteCount number := 0;
procedure reset_counter is
begin
vUpdateCount := 0;
vInsertCount := 0;
vDeleteCount := 0;
end;
procedure count_insert is
begin
vInsertCount := vInsertCount + 1;
end;
procedure count_update is
begin
vUpdateCount := vUpdateCount + 1;
end;
procedure count_delete is
begin
vDeleteCount := vDeleteCount + 1;
end;
function get_insert_count return number is
begin
return vInsertCount;
end;
function get_update_count return number is
begin
return vUpdateCount;
end;
function get_delete_count return number is
begin
return vDeleteCount;
end;
end;
単一の DML ステートメントの実行中に行数をカウントするには、ステートメント トリガーの前にリセットする必要があります。
create or replace trigger trg_test_table_counter_reset
before insert or update or delete on test_table
begin
pkg_test_table_counter.reset_counter;
end;
...そして、各行のトリガーで適切なカウンターを増やします:
create or replace trigger trg_test_table_counter_count
before insert or update or delete on test_table
for each row
begin
if inserting then
pkg_test_table_counter.count_insert;
end if;
if updating then
pkg_test_table_counter.count_update;
end if;
if deleting then
pkg_test_table_counter.count_delete;
end if;
end;
したがって、MERGE
DML クエリ テキスト内で追加のトリックを使用せずにステートメントを実行すると、影響を受ける行の正確な数を常に取得できます。
select
pkg_test_table_counter.get_insert_count insert_count,
(
pkg_test_table_counter.get_update_count
-
pkg_test_table_counter.get_delete_count
) update_count,
pkg_test_table_counter.get_delete_count delete_count
from dual
削除操作も の更新としてカウントされることに注意してください。ただしMERGE
、別の操作でパッケージを有効に保つために、2 つの個別のカウンターがあります。