2009-05-14 17 views
124

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

答えて

194

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

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

:代わり

DECLARE 
    i number; 
BEGIN 
    UPDATE employees 
    SET status = 'fired' 
    WHERE name like '%Bloggs'; 
    i := sql%rowcount; 
END; 
6

SQL%ROWCOUNT あなたは、プレーンなコマンドからの結果をしたい人のための変数

+3

のSQL%のROWCOUNTが関数である、あなただけの「それを使用する」ことはできません - あなたは*それを*何かをする必要があり - 変数に格納するか、別のプロシージャに入力として送信するか、それを別のプロシージャに追加するかどうか。 –

+7

Ali Hのポイントは、行数に影響を与える別のSQL文があるまで、変数に割り当てる必要がないということです。つまり、誰かが呼び出される前に別のSQL文を追加すると、後でバグが発生するのを避けるために変数に代入する必要があるということに同意します。そして、Ali Hからのこの回答は、別の回答として投稿されているのではなく、Cliveの回答に対するコメントでなければなりません。 – Kirby

18

を宣言する必要なく、プロシージャ内でソリューションをこれを使用することができます可能性があり次のようになります。

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

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

...誰かがSELECTコマンドで使用するソリューションを持っているなら、私は興味があります。

-3

+0

実際に更新した件数を確認した場合、更新ステートメントを実行した後 - たとえば、私のテーブルTに、すべての値として「1」を含む1つの列c1がある場合、その列のすべての行を「2」に更新すると、どのようにNullによる分割が役立ちますか? – nanosoft

1

SQL%ROWCOUNTの総数をカウントしますCOUNT(*)NULL これBY PARTITION OVER解析関数を使用しても(少なくともOracle 11gのから)割り当てされることなく使用することができます。

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

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; 

は、我々はこのようにそれをテストしますテーブルのクライアントに

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

を持っていると言います結果:

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 
0

、このいずれかを試してみてください。..


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; 

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

結果は以下のようになります:1
クライアントを使用しないため、更新


2クライアント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

メッセージを正しくフォーマットできますか? –

関連する問題