Кількість рядків, на які впливає UPDATE в PL / SQL


162

У мене є функція PL / SQL (працює на Oracle 10g), в якій я оновлюю деякі рядки. Чи є спосіб дізнатися, на скільки рядків вплинуло ОНОВЛЕННЯ? Під час виконання запиту вручну він повідомляє мені, на скільки рядків вплинуло, я хочу отримати це число в PL / SQL.

Відповіді:


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
І завдання має передувати будь-яким COMMITs
rshdev

@Clive У мене є процедура з INSERT INTO.., COMMITа також у тій же процедурі після вставки, що і у мене UPDATE SET WHERE EXISTS..COMMIT, але моя i := SQL%rowcount;повертає всі рядки замість рядків, які були оновлені лише. Що може бути?
Гільгерме Матей

26

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

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

Основна проблема полягає в тому, що SQL% ROWCOUNT є змінною PL / SQL (або функцією), і до неї не можна отримати прямий доступ із команди SQL. За допомогою блоку alo PL / SQL цього можна досягти.

... Якщо хтось має рішення використовувати його в команді SELECT, я був би зацікавлений.


6

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


4
SQL% ROWCOUNT - це функція, яку ви не можете просто "використати" - вам потрібно зробити щось з нею - чи зберігання в змінній, або надсилання її як вхід до іншої процедури, або додавання її до чогось іншого.
Джеффрі Кемп

8
Я думаю, що пункт Алі Н полягає в тому, що не потрібно призначати його змінній, поки у вас є інший оператор SQL, який би впливав на кількість рядків. Зважаючи на це, я погоджуюся, що вона повинна бути присвоєна змінній, щоб потім не викликати помилку, якщо хтось додасть інший оператор SQL перед тим, як його викликати. І ця відповідь від Алі Х повинна бути коментарем до відповіді Клайва, а не розміщеною як окрема відповідь
Кірбі

1

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

Поки жодна операція (оновлення, видалення або вставки) не виконується в поточному блоці, SQL%ROWCOUNTвстановлена ​​на нуль. Потім він залишається з числом рядка, на який впливає остання операція 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

-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 (*) ЗА ПАРТІЄНТУ НА NULL. Підраховується загальна кількість рядків


Після запуску заяви оновлення, якщо ви перевіряєте рахунок на те, що ви насправді оновили - Це не дає ніякого загального рішення. Наприклад, якщо в моїй таблиці T є один стовпець c1, який містить значення "1" для всіх, і тепер я оновлюю всі рядки для цього стовпця до "2", як розділення за допомогою null допоможе?
nanosoft
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.