Количество строк, затронутых ОБНОВЛЕНИЕМ в PL/SQL
У меня есть функция PL/SQL (работает на Oracle 10g), в которой я обновляю некоторые строки. Есть ли способ узнать, на сколько строк повлияло ОБНОВЛЕНИЕ? При выполнении запроса вручную он сообщает мне, сколько строк было затронуто, я хочу получить это число в PL/SQL.
6 ответов
Вы используете sql%rowcount
переменная.
Вы должны вызывать его сразу после оператора, для которого нужно найти число затронутых строк.
Например:
DECLARE
i number;
BEGIN
UPDATE employees
SET status = 'fired'
WHERE name like '%Bloggs';
i := sql%rowcount;
END;
Для тех, кто хочет получить результаты от простой команды, решение может быть:
begin
DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||' rows affected.');
end;
Основная проблема заключается в том, что SQL%ROWCOUNT является переменной (или функцией) PL/SQL, и к ней нельзя получить прямой доступ из команды SQL. С помощью блока PL/SQL без имени это может быть достигнуто.
... Если у кого-то есть решение использовать его в команде SELECT, мне было бы интересно.
В качестве альтернативы, SQL%ROWCOUNT
Вы можете использовать это в процедуре без необходимости объявлять переменную
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
Примерьте вот это..
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
Используйте аналитическую функцию Count(*). OVER PARTITION BY NULL Это будет считать общее количество строк