ChatGPT解决这个技术问题 Extra ChatGPT

PL/SQL 中受 UPDATE 影响的行数

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


T
Toolkit

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

并且赋值必须在任何 COMMIT 之前
@Clive 我有一个带有 INSERT INTO..COMMIT 的过程,并且在插入后的同一过程中,我有 UPDATE SET WHERE EXISTS..COMMIT,但我的 i := SQL%rowcount; 正在返回所有行而不是更新的行只要。可能是什么?
C
CLS

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

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

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

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


A
Ali H

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


SQL%ROWCOUNT 是一个函数,你不能只是“使用它”——你需要用它做一些事情——无论是存储在一个变量中,还是将它作为输入发送到另一个过程,或者将它添加到其他东西。
我认为 Ali H 的观点是,在您有另一个会影响行数的 SQL 语句之前,没有必要将其分配给变量。话虽如此,我同意应该将它分配给一个变量,以避免以后如果有人在调用它之前添加另一个 SQL 语句而导致错误。而且,来自 Ali H 的这个答案应该是对 Clive 答案的评论,而不是作为单独的答案发布
J
J. Chomel

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

A
Arun Sundriyal

请试试这个..

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;

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

结果将如下所示:

客户端更新为 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


为您的解决方案添加评论,请具体说明。
g
guest

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


运行更新语句后,如果您检查实际更新内容的计数 - 这并没有提供任何通用解决方案。例如,如果我的表 T 有一个列 c1,其中包含“1”作为 all 的值,现在我将该列的所有行更新为“2”,那么 null 分区将如何帮助?