一部の行を更新するPL/SQL関数(Oracle 10gで実行)があります。 UPDATEの影響を受けた行数を調べる方法はありますか?クエリを手動で実行すると、影響を受けた行数がわかります。PL/ SQLでその数を取得します。
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;
単純なコマンドの結果が必要な場合、解決策は次のとおりです。
begin
DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||' rows affected.');
end;
基本的な問題は、SQL%ROWCOUNTはPL/SQL変数(または関数)であり、SQLコマンドから直接アクセスできないことです。 noname PL/SQLブロックを使用すると、これを実現できます。
...誰かがそれをSELECTコマンドで使用する解決策を持っているなら、私は興味があるでしょう。
または、SQL%ROWCOUNT
、変数を宣言する必要なくプロシージャ内でこれを使用できます
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
これをお試し下さい..
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