Số lượng hàng bị ảnh hưởng bởi CẬP NHẬT trong PL / SQL


162

Tôi có một hàm PL / SQL (chạy trên Oracle 10g) trong đó tôi cập nhật một số hàng. Có cách nào để tìm hiểu có bao nhiêu hàng bị ảnh hưởng bởi CẬP NHẬT không? Khi thực hiện truy vấn theo cách thủ công, nó cho tôi biết có bao nhiêu hàng bị ảnh hưởng, tôi muốn lấy số đó trong PL / SQL.

Câu trả lời:


245

Bạn sử dụng sql%rowcountbiến.

Bạn cần gọi thẳng sau câu lệnh mà bạn cần tìm số hàng bị ảnh hưởng.

Ví dụ:

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
Và nhiệm vụ phải đi trước bất kỳ
CAM KẾT

@Clive Tôi đã có một quy trình với INSERT INTO.. COMMITvà cũng trong quy trình tương tự sau khi chèn, tôi có UPDATE SET WHERE EXISTS..COMMIT, nhưng tôi i := SQL%rowcount;đang trả lại tất cả các hàng thay vì các hàng chỉ được cập nhật. Điều gì có thể?
Guilherme Matheus

26

Đối với những người muốn kết quả từ một lệnh đơn giản, giải pháp có thể là:

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

Vấn đề cơ bản là SQL% ROWCOUNT là biến PL / SQL (hoặc hàm) và không thể được truy cập trực tiếp từ lệnh SQL. Bằng cách sử dụng khối PL / SQL không tên, điều này có thể đạt được.

... Nếu bất cứ ai có giải pháp sử dụng nó trong Lệnh CHỌN, tôi sẽ thấy hứng thú.


6

cách khác, SQL%ROWCOUNT bạn có thể sử dụng điều này trong thủ tục mà không cần phải khai báo một biến


4
SQL% ROWCOUNT là một hàm, bạn không thể chỉ "sử dụng nó" - bạn cần phải làm gì đó với nó - cho dù lưu trữ trong một biến, hoặc gửi nó làm đầu vào cho một thủ tục khác, hoặc thêm nó vào một thứ khác.
Jeffrey Kemp

8
Tôi nghĩ rằng quan điểm của Ali H là không cần thiết phải gán nó cho một biến cho đến khi bạn có một câu lệnh SQL khác sẽ ảnh hưởng đến số hàng. Điều đó đang được nói, tôi đồng ý rằng nó nên được gán cho một biến để tránh gây ra lỗi sau này nếu ai đó thêm một câu lệnh SQL khác trước khi nó được gọi. Và, câu trả lời này của Ali H nên là một nhận xét về câu trả lời của Clive thay vì được đăng dưới dạng một câu trả lời riêng
Kirby

1

SQL%ROWCOUNTcũng có thể được sử dụng mà không được chỉ định (ít nhất là từ Oracle 11g ).

Miễn là không có thao tác (cập nhật, xóa hoặc chèn) nào được thực hiện trong khối hiện tại, SQL%ROWCOUNTđược đặt thành null. Sau đó, nó vẫn ở với số lượng dòng bị ảnh hưởng bởi hoạt động DML cuối cùng:

nói rằng chúng tôi có bảng KHÁCH HÀNG

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

Chúng tôi sẽ kiểm tra nó theo cách này:

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;

Kết quả là:

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

Hãy thử cái này ..


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;

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

Kết quả sẽ như dưới đây:


2 khách hàng được cập nhật cho 1
khách hàng không có 2 val_cli.
không có khách hàng với 3 val_cli.
1 khách hàng được cập nhật cho 4
khách hàng không có 5 val_cli.
1 khách hàng được cập nhật cho 6
khách hàng không có 7 val_cli.
không có khách hàng với 8 val_cli.
không có khách hàng nào với 9 val_cli.
1 khách hàng được cập nhật cho 10
Số lượng tổng số dòng bị ảnh hưởng hoạt động cập nhật: 5



Thêm ý kiến ​​cho giải pháp của bạn, Hãy cụ thể.
Kumar Abhishek

-3

Sử dụng hàm phân tích Count (*) QUÁ THAM GIA BỞI NULL Điều này sẽ đếm tổng số # hàng


Sau khi chạy câu lệnh cập nhật nếu bạn kiểm tra số lượng trên những gì bạn thực sự cập nhật - Điều này không đưa ra bất kỳ giải pháp chung nào. Ví dụ: nếu bảng T của tôi có một cột c1 chứa "1" làm giá trị cho tất cả và bây giờ tôi cập nhật tất cả các hàng cho cột đó thành "2", thì phân vùng bằng null sẽ giúp như thế nào?
nanosoft
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.