PL / SQL'de bir UPDATE'ten etkilenen satır sayısı


162

Bazı satırları güncellediğim bir PL / SQL işlevi (Oracle 10g üzerinde çalışan) var. GÜNCELLEME'den kaç satır etkilendiğini öğrenmenin bir yolu var mı? Sorguyu manuel olarak yürütürken kaç satır etkilendiğini söyler, PL / SQL'de bu sayıyı almak istiyorum.

Yanıtlar:


245

sql%rowcountDeğişkeni kullanırsınız .

Etkilenen satır sayısını bulmanız gereken ifadeden hemen sonra çağırmanız gerekir.

Örneğin:

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
Ve atama herhangi bir KOMİT'ten önce gelmelidir
rshdev

@Clive INSERT INTO.. ile bir prosedür var COMMITve aynı prosedürü ekledikten sonra var UPDATE SET WHERE EXISTS..COMMIT, ama benim i := SQL%rowcount;sadece güncellenen satırlar yerine tüm satırları döndürüyor. Ne olabilir?
Guilherme Matheus

26

Düz bir komuttan sonuç almak isteyenler için çözüm şöyle olabilir:

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

Temel sorun, SQL% ROWCOUNT bir PL / SQL değişkeni (veya işlevi) olması ve bir SQL komutundan doğrudan erişilememesidir. Adsız bir PL / SQL bloğu kullanılarak bu gerçekleştirilebilir.

... Birisinin bir SELECT Komutunda kullanmak için bir çözümü varsa, ilgilenirim.


6

alternatif olarak, SQL%ROWCOUNT bunu değişken içinde bildirmeye gerek kalmadan prosedür içinde kullanabilirsiniz


4
Gerekirse - SQL% ROWCOUNT bir işlev, sadece "kullanmak" olamaz yapmak onunla bir şey - bir değişkende saklamak veya başka bir prosedüre girdi olarak gönderip, veya başka bir şey eklemeden olsun.
Jeffrey Kemp

8
Ali H'ın amacı, satır sayısını etkileyecek başka bir SQL ifadesi olana kadar bir değişkene atamanın gerekli olmadığını düşünüyorum. Olduğu söyleniyor, daha sonra birisi çağrılmadan önce başka bir SQL ifadesi eklemeniz durumunda bir hataya neden olmamak için bir değişkene atanması gerektiğini kabul ediyorum. Ve Ali H'den gelen bu cevap, ayrı bir cevap olarak değil de Clive'nin cevabı hakkında bir yorum olmalı
Kirby

1

SQL%ROWCOUNTatanmadan da kullanılabilir (en azından Oracle 11g'den) ).

Geçerli blok içinde hiçbir işlem (güncelleme, silme veya ekleme) gerçekleştirilmediği sürece SQL%ROWCOUNTnull olarak ayarlanır. Ardından, son DML işleminden etkilenen satır sayısı ile kalır:

MÜŞTERİ masamız var diyelim

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

Bunu şu şekilde test ederiz:

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;

Sonuçlanan:

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

Lütfen bunu deneyin..


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;

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

Sonuç aşağıdaki gibi olacaktır:


2 istemci 1 güncellendi 2 istemci
2 val_cli ile.
3 val_cli ile müşteri yok.
1 müşteri güncellendi 4
istemci 5 val_cli ile.
1 istemci güncellendi 6
istemci 7 val_cli ile.
8 val_cli ile müşteri yok.
9 val_cli ile müşteri yok.
1 müşteri 10 için
güncellendi Güncelleme işleminden etkilenen toplam satır sayısı: 5



Çözümünüze yorum ekleyin, Lütfen spesifik olun.
Kumar Abhishek

-3

Count (*) analitik fonksiyonunu kullanın NULL BY BY PARTITION ÜZERİNDE Bu, toplam satır sayısını sayar


Güncelleme ifadesini çalıştırdıktan sonra, gerçekten neyi güncellediğinize dair sayıyı kontrol ederseniz - Bu herhangi bir genel çözüm sağlamaz. Örneğin, T tablomda herkes için değer olarak "1" içeren bir sütun c1 varsa ve şimdi bu sütun için tüm satırları "2" olarak güncellersem null ile bölümleme nasıl yardımcı olur?
nanosoft
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.