PL / SQLのUPDATEの影響を受ける行数


162

一部の行を更新するPL / SQL関数(Oracle 10gで実行)があります。UPDATEの影響を受けた行数を確認する方法はありますか?クエリを手動で実行すると、影響を受けた行数がわかります。その数をPL / SQLで取得したいと考えています。

回答:


245

sql%rowcount変数を使用します。

影響を受ける行数を見つける必要があるステートメントの直後にそれを呼び出す必要があります。

例えば:

set serveroutput ON; 
DECLARE 
    i NUMBER; 
BEGIN 
    UPDATE employees 
    SET    status = 'fired' 
    WHERE  name LIKE '%Bloggs'; 
    i := SQL%rowcount; 
    --note that assignment has to precede COMMIT
    COMMIT; 
    dbms_output.Put_line(i); 
END; 

4
そして、割り当てはすべてのCOMMITに先行する必要があります
rshdev

@Clive INSERT INTO.. COMMITを使用したプロシージャがあり、挿入後の同じプロシージャにもがありますUPDATE SET WHERE EXISTS..COMMITが、i := SQL%rowcount;更新された行だけではなく、すべての行が返されます。何でしょうか?
ギルヘルメマテウス

26

単純なコマンドからの結果が必要な場合、解決策は次のようになります。

begin
  DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||' rows affected.');
end;

基本的な問題は、SQL%ROWCOUNTがPL / SQL変数(または関数)であり、SQLコマンドから直接アクセスできないことです。noname PL / SQLブロックを使用すると、これを実現できます。

...誰かがSELECTコマンドでそれを使用する解決策を持っているなら、私は興味があります。


6

または、SQL%ROWCOUNT 変数を宣言する必要なく、プロシージャ内でこれを使用できます


4
SQLの%のROWCOUNTが関数である、あなただけの「それを使用する」ことはできません-あなたがする必要がありません変数に格納し、または他の手順への入力としてそれを送る、または何か他のものにそれを追加するかどうか-それで何かを。
Jeffrey Kemp、2012

8
Ali Hのポイントは、行数に影響を与える別のSQLステートメントが作成されるまで、変数に割り当てる必要がないということです。そうは言っても、誰かが別のSQLステートメントを呼び出す前に追加した場合に後でバグが発生するのを避けるために、変数に割り当てる必要があることに同意します。そして、アリHからこの答えは、別の答えとして掲載するのではなくクライヴの答えにコメントする必要があります
星のカービィ

1

SQL%ROWCOUNT割り当てなくても使用できます(少なくともOracle 11gから)。

現在のブロック内で操作(更新、削除、または挿入)が実行されていない限り、SQL%ROWCOUNTnullに設定されます。次に、最後のDML操作によって影響を受けた行数が残ります。

テーブルCLIENTがあるとしましょう

create table client (
  val_cli integer
 ,status varchar2(10)
)
/

次のようにテストします。

begin
  dbms_output.put_line('Value when entering the block:'||sql%rowcount);

  insert into client 
            select 1, 'void' from dual
  union all select 4, 'void' from dual
  union all select 1, 'void' from dual
  union all select 6, 'void' from dual
  union all select 10, 'void' from dual;  
  dbms_output.put_line('Number of lines affected by previous DML operation:'||sql%rowcount);

  for val in 1..10
    loop
      update client set status = 'updated' where val_cli = val;
      if sql%rowcount = 0 then
        dbms_output.put_line('no client with '||val||' val_cli.');
      elsif sql%rowcount = 1 then
        dbms_output.put_line(sql%rowcount||' client updated for '||val);
      else -- >1
        dbms_output.put_line(sql%rowcount||' clients updated for '||val);
      end if;
  end loop;  
end;

その結果:

Value when entering the block:
Number of lines affected by previous DML operation:5
2 clients updated for 1
no client with 2 val_cli.
no client with 3 val_cli.
1 client updated for 4
no client with 5 val_cli.
1 client updated for 6
no client with 7 val_cli.
no client with 8 val_cli.
no client with 9 val_cli.
1 client updated for 10

-1

これをお試し下さい..


create table client (
  val_cli integer
 ,status varchar2(10)
);

---------------------
begin
insert into client
select 1, 'void' from dual
union all
select 4, 'void' from dual
union all
select 1, 'void' from dual
union all
select 6, 'void' from dual
union all
select 10, 'void' from dual;
end;

---------------------
select * from client;

---------------------
declare
  counter integer := 0;
begin
  for val in 1..10
    loop
      update client set status = 'updated' where val_cli = val;
      if sql%rowcount = 0 then
        dbms_output.put_line('no client with '||val||' val_cli.');
      else
        dbms_output.put_line(sql%rowcount||' client updated for '||val);
        counter := counter + sql%rowcount;
      end if;
  end loop;
   dbms_output.put_line('Number of total lines affected update operation: '||counter);
end;

---------------------
select * from client;

--------------------------------------------------------

結果は以下のようになります。


2
つのval_cliを使用して、1つのクライアントなしで2つのクライアントを更新しました。
3 val_cliのクライアントはありません。
1つ
のクライアントが4つのクライアントに更新され、5つのval_cliがありません。
1つのクライアントが6つ
のクライアントに更新され、7つのval_cliでクライアントがありません。
8 val_cliのクライアントはありません。
9 val_cliのクライアントはありません。
1クライアントが10更新されました
更新操作に影響を与えた合計行数:5



ソリューションにコメントを追加してください。具体的に説明してください。
Kumar Abhishek

-3

Count(*)分析関数を使用します。OVERPARTITION BY NULLは、行の総数をカウントします。


実際に更新したものの数を確認すると、updateステートメントを実行した後-これは一般的な解決策を提供しません。たとえば、テーブルTにすべての値として「1」を含む1つの列c1があり、その列のすべての行を「2」に更新した場合、nullによるパーティション分割はどのように役立ちますか?
nanosoft 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.