[Oracle] Количество строк, затронутых UPDATE в PL / SQL


Answers

Вы используете переменную sql%rowcount .

Вам нужно вызвать его сразу после утверждения, которое вам нужно найти для подсчета числа строк.

Например:

DECLARE
    i number;
BEGIN
    UPDATE employees
    SET status = 'fired'
    WHERE name like '%Bloggs';
    i := sql%rowcount;
END;
Question

У меня есть функция PL / SQL (работает на Oracle 10g), в которой я обновляю некоторые строки. Есть ли способ узнать, сколько строк повлияло на UPDATE? При выполнении запроса вручную он сообщает мне, сколько строк было затронуто, я хочу получить этот номер в PL / SQL.




Примерьте вот это..

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




Для тех, кто хочет получить результаты из простой команды, решение может быть:

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

Основная проблема заключается в том, что SQL% ROWCOUNT - это переменная (или функция) PL / SQL и не может быть напрямую доступна из команды SQL. Используя блок noname PL / SQL, это может быть достигнуто.

... Если у кого-то есть решение использовать его в команде SELECT, мне было бы интересно.




SQL%ROWCOUNT также может использоваться без назначения (по крайней мере, от Oracle 11g ).

Пока в текущем блоке не выполнялась никакая операция (обновления, удаления или вставки), SQL%ROWCOUNT имеет значение null. Затем он остается с числом строк, затронутым последней операцией DML:

скажем, у нас есть стол КЛИЕНТ

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



альтернативно, SQL%ROWCOUNT вы можете использовать это в рамках процедуры, без необходимости объявлять переменную




Используйте аналитическую функцию Count (*) OVER PARTITION NULL. Это будет считать общее количество строк