Oracle PL/SQL中受更新影响的行数

Oracle PL/SQL中受更新影响的行数,oracle,plsql,sql-update,Oracle,Plsql,Sql Update,我在Oracle10g上运行了一个PL/SQL函数,其中更新了一些行。有没有办法找出受更新影响的行数?手动执行查询时,它会告诉我有多少行受到影响,我希望在PL/SQL中获取该数字。您使用SQL%rowcount变量 您需要在语句之后直接调用它,以查找受影响的行数 例如: set serveroutput ON; DECLARE i NUMBER; BEGIN UPDATE employees SET status = 'fired' WHERE

我在Oracle10g上运行了一个PL/SQL函数,其中更新了一些行。有没有办法找出受更新影响的行数?手动执行查询时,它会告诉我有多少行受到影响,我希望在PL/SQL中获取该数字。

您使用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; 
或者,使用SQL%ROWCOUNT
您可以在过程中使用此选项,而无需声明变量。对于希望从普通命令中获得结果的用户,解决方案可以是:

begin
  DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||' rows affected.');
end;
基本问题是SQL%ROWCOUNT是PL/SQL变量或函数,不能直接从SQL命令访问。通过使用非名称PL/SQL块,可以实现这一点


。。。如果有人有在SELECT命令中使用它的解决方案,我会感兴趣。

使用Count*分析函数除以NULL进行分区 这将计算行总数

SQL%ROWCOUNT也可以使用,而无需至少从Oracle 11g分配

只要当前块中没有执行任何操作更新、删除或插入,SQL%ROWCOUNT就会设置为null。然后,它保持受上次DML操作影响的线路数:

假设我们有一个桌面客户端

我们将通过以下方式进行测试:

导致:

请试试这个

结果如下所示:

为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


SQL%ROWCOUNT是一个函数,你不能仅仅使用它——你需要对它做些什么——无论是存储在变量中,还是将它作为输入发送到另一个过程,或者将它添加到其他过程。我认为Ali H的观点是,在你有另一个SQL语句影响行数之前,没有必要将它分配给变量。也就是说,我同意应该将它分配给一个变量,以避免以后在调用之前有人添加另一个SQL语句时导致错误。而且,如果您检查实际更新内容的数量,Ali H的回答应该是对Clive回答的评论,而不是在运行update语句后作为单独的回答发布-这没有给出任何通用的解决方案。例如,如果我的表T有一列c1,其中包含1作为all的值,现在我将该列的所有行更新为2,那么按null进行分区将如何帮助?并且赋值必须在任何列之前COMMITs@Clive我有一个INSERT INTO..COMMIT的过程,在INSERT之后的同一个过程中,我有一个更新集,其中存在..COMMIT,但是我的i:=SQL%rowcount;正在返回所有行,而不是仅更新的行。可能是什么?请在您的解决方案中添加注释,请具体说明。
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
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;

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