受PL / SQL中的UPDATE影响的行数


162

我有一个PL / SQL函数(在Oracle 10g上运行),在其中更新了一些行。有没有办法找出UPDATE影响了多少行?手动执行查询时,它告诉我受影响的行数,我想在PL / SQL中获得该数字。

Answers:


245

您使用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; 

4
并且分配必须在任何
COMMIT

@Clive我有一个使用INSERT INTO.. 的过程,COMMIT并且在插入后也有相同的过程,我有UPDATE SET WHERE EXISTS..COMMIT,但是我i := SQL%rowcount;将返回所有行,而不是仅更新的行。可能是什么?
Guilherme Matheus,

26

对于那些希望从普通命令获得结果的人,解决方案可能是:

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

基本问题是SQL%ROWCOUNT是一个PL / SQL变量(或函数),不能从SQL命令直接访问。通过使用noname PL / SQL块,可以实现这一点。

...如果任何人都有在SELECT命令中使用它的解决方案,我将很感兴趣。


6

或者,SQL%ROWCOUNT 您可以在过程中使用它,而无需声明变量


4
SQL%ROWCOUNT是一个函数,您不能只是“使用它”-您需要对它做些事-无论是存储在变量中,还是将其作为输入发送到另一个过程,或将其添加到其他过程中。
杰弗里·肯普

8
我认为Ali H的要点是,直到您有另一个会影响行数的SQL语句,才有必要将其分配给变量。话虽如此,我同意应该将其分配给变量,以避免在有人在调用之前添加另一个SQL语句的情况下避免引起错误。而且,来自Ali H的答案应该是对Clive答案的评论,而不是作为单独的答案发布
Kirby 2014年

1

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

-1

请试试这个..


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



在您的解决方案中添加评论,请具体说明。
库玛·阿比舍克

-3

使用Count(*)分析函数OVER PARTITION BY NULL这将计算总行数


在运行update语句后,如果您检查实际更新的数量,则不会提供任何通用解决方案。例如,如果我的表T有一个列c1,其中所有列的值都包含“ 1”,现在我将该列的所有行更新为“ 2”,那么如何通过null帮助进行分区?
nanosoft '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.