1

PL/SQL スクリプトで MERGE DML ステートメントを使用しているときに、PL/SQL で更新された行数と挿入された行数の情報を受け取る方法があるかどうかを知りたいです。

ここで説明されているマージの Oracle の例を使用してみましょう: MERGE の例

この機能は関数で使用されていますが、更新された行数と挿入された行数の情報もログに記録したいと考えています。

4

2 に答える 2

5

挿入数と更新数を別々に取得する組み込みの方法はありません。SQL%ROWCOUNTおそらくすでにご存知のように、マージされた行数がわかりますが、挿入と更新の個別の値を取得するのに相当するものはありません。

Adrian Billington によるこの記事では、マージに関数呼び出しを含めることで情報を取得する方法を示していますが、これによりオーバーヘッドが少し増える可能性があります。

同様の、おそらくもっと単純なトリックが Oracle フォーラムに MichaelS からあります。ここで再現したくなりますが、それが許可されているかどうかはわかりませんが、基本的にはsys_context、エイドリアンのソリューションがパッケージ変数で行ったのとほぼ同じ方法で、カウントを維持するために使用しています. よりクリーンで、フォローとメンテナンスが簡単だと思うので、私はそれを使用します。

まだリンクのみの回答に危険なほど近いですが、他の人の作品を盗用したくありません...

于 2013-10-03T10:41:11.640 に答える
3

@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;

したがって、MERGEDML クエリ テキスト内で追加のトリックを使用せずにステートメントを実行すると、影響を受ける行の正確な数を常に取得できます。

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 つの個別のカウンターがあります。

SQLFiddle test

于 2013-10-03T12:18:13.480 に答える