Вопрос:
У меня есть функция PL/SQL (работает на Oracle 10g), в которой я обновляю некоторые строки. Есть ли способ узнать, сколько строк повлияло на UPDATE? При выполнении запроса вручную он сообщает мне, сколько строк было затронуто, я хочу получить этот номер в 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; Ответ №1
Для тех, кто хочет получить результаты из простой команды, решение может быть:
begin DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||’ rows affected.’); end;
Основная проблема заключается в том, что SQL% ROWCOUNT – это переменная (или функция) PL/SQL и не может быть напрямую доступна из команды SQL. Используя блок noname PL/SQL, это может быть достигнуто.
… Если у кого-то есть решение использовать его в команде SELECT, мне было бы интересно.
Ответ №2
SQL%ROWCOUNT
вы можете использовать это в процедуре без необходимости объявлять переменную
Ответ №3
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 Ответ №4
Примерьте вот это..
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
Ответ №5
Используйте аналитическую функцию Count (*) OVER PARTITION by NULL
Это будет считать общее количество строк