Jumlah baris yang dipengaruhi oleh PEMBARUAN dalam PL / SQL

162

Saya memiliki fungsi PL / SQL (berjalan pada Oracle 10g) di mana saya memperbarui beberapa baris. Apakah ada cara untuk mengetahui berapa banyak baris yang terpengaruh oleh UPDATE? Ketika menjalankan kueri secara manual, ini memberitahu saya berapa banyak baris yang terpengaruh, saya ingin mendapatkan nomor itu dalam PL / SQL.

Thomas Lötzer
sumber

Jawaban:

245

Anda menggunakan sql%rowcountvariabel.

Anda perlu menyebutnya langsung setelah pernyataan yang Anda butuhkan untuk menemukan jumlah baris yang terpengaruh.

Sebagai contoh:

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; 
Clive
sumber
4
Dan penugasan harus mendahului setiap KOMIT
rshdev
@Clive Saya punya prosedur dengan INSERT INTO.. COMMITdan juga dalam prosedur yang sama setelah memasukkan, saya punya UPDATE SET WHERE EXISTS..COMMIT, tapi saya i := SQL%rowcount;mengembalikan semua baris bukan baris yang hanya diperbarui. Apa yang bisa
Guilherme Matheus
26

Bagi mereka yang menginginkan hasil dari perintah sederhana, solusinya dapat:

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

Masalah dasar adalah bahwa SQL% ROWCOUNT adalah variabel PL / SQL (atau fungsi), dan tidak dapat diakses langsung dari perintah SQL. Dengan menggunakan blok PL / SQL noname, ini dapat dicapai.

... Jika ada yang punya solusi untuk menggunakannya dalam Perintah SELECT, saya akan tertarik.

CLS
sumber
6

sebagai alternatif, SQL%ROWCOUNT Anda dapat menggunakan ini dalam prosedur tanpa perlu mendeklarasikan variabel

Ali H
sumber
4
SQL% ROWCOUNT adalah suatu fungsi, Anda tidak bisa hanya "menggunakannya" - Anda perlu melakukan sesuatu dengannya - apakah menyimpan dalam variabel, atau mengirimkannya sebagai input ke prosedur lain, atau menambahkannya ke sesuatu yang lain.
Jeffrey Kemp
8
Saya pikir poin Ali H adalah bahwa tidak perlu untuk menetapkannya ke variabel sampai Anda memiliki pernyataan SQL lain yang akan mempengaruhi jumlah baris. Yang sedang berkata, saya setuju bahwa itu harus ditugaskan ke variabel untuk menghindari menyebabkan bug nanti jika seseorang menambahkan pernyataan SQL lain sebelum dipanggil. Dan, jawaban dari Ali H ini seharusnya menjadi komentar atas jawaban Clive dan bukannya diposting sebagai jawaban yang terpisah
Kirby
1

SQL%ROWCOUNTjuga dapat digunakan tanpa ditugaskan (setidaknya dari Oracle 11g ).

Selama tidak ada operasi (pembaruan, penghapusan atau penyisipan) telah dilakukan dalam blok saat ini, SQL%ROWCOUNTdiatur ke nol. Kemudian tetap dengan jumlah garis yang dipengaruhi oleh operasi DML terakhir:

katakanlah kita memiliki tabel KLIEN

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

Kami akan mengujinya dengan cara ini:

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;

Yang menghasilkan:

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
J. Chomel
sumber
-1

Silakan coba yang ini ..


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;

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

Hasilnya akan seperti di bawah ini:


2 klien diperbarui untuk 1
tanpa klien dengan 2 val_cli.
tidak ada klien dengan 3 val_cli.
1 klien diperbarui untuk 4
tanpa klien dengan 5 val_cli.
1 klien diperbarui untuk 6
tanpa klien dengan 7 val_cli.
tidak ada klien dengan 8 val_cli.
tidak ada klien dengan 9 val_cli.
1 klien diperbarui untuk 10
Jumlah total baris yang terpengaruh operasi pembaruan: 5


Arun Sundriyal
sumber
Tambahkan komentar ke solusi Anda, Harap spesifik.
Kumar Abhishek
-3

Gunakan fungsi analitik Count (*) OVER PARTITION BY NULL Ini akan menghitung total # baris

tamu
sumber
Setelah menjalankan pernyataan pembaruan jika Anda memeriksa jumlah yang benar-benar diperbarui - ini tidak memberikan solusi umum. Misalnya, jika tabel saya T memiliki satu kolom c1 yang berisi "1" sebagai nilai untuk semua dan sekarang saya memperbarui semua baris untuk kolom itu menjadi "2", bagaimana cara mempartisi dengan bantuan nol?
nanosoft