web-dev-qa-db-ja.com

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

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

150
Thomas Lötzer

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; 
225
Clive

単純なコマンドの結果が必要な場合、解決策は次のとおりです。

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

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

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

23
CLS

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

6
Ali H

SQL%ROWCOUNTは、割り当てられずに使用することもできます(少なくともOracle 11gから)。

現在のブロック内で操作(更新、削除、または挿入)が実行されていない限り、SQL%ROWCOUNTはnullに設定されます。その後、最後の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
J. Chomel

これをお試し下さい..


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クライアントが1に更新されました
2つのval_cliを持つクライアントはありません。
3つのval_cliを持つクライアントはありません。
1クライアントが4に更新されました
5 val_cliのクライアントはありません。
1クライアントを6に更新
7 val_cliのクライアントはありません。
8 val_cliのクライアントはありません。
9 val_cliのクライアントはありません。
1クライアントを10に更新
更新操作に影響する合計行数:5


0
Arun Sundriyal