Número de linhas afectadas por uma actualização em PL / SQL
Tenho uma função PL / SQL (a correr no Oracle 10g) na qual actualizo algumas linhas. Existe uma maneira de descobrir quantas linhas foram afetadas pela atualização? Ao executar a consulta manualmente, ele me diz quantas linhas foram afetadas, eu quero obter esse número em PL / SQL.
6 answers
Usa a variável sql%rowcount
.
Você precisa chamá-lo imediatamente após a declaração que você precisa para encontrar a contagem de linha afectada.
Por exemplo:
DECLARE
i number;
BEGIN
UPDATE employees
SET status = 'fired'
WHERE name like '%Bloggs';
i := sql%rowcount;
END;
Para aqueles que querem os resultados de um comando simples, a solução pode ser:
begin
DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||' rows affected.');
end;
O problema básico é que o SQL%ROWCOUNT é uma variável PL/SQL (ou função), e não pode ser acedido directamente a partir de um comando SQL. Usando um bloco PL/SQL noname, isso pode ser alcançado.
... Se alguém tem uma solução para usá-la em um comando selecionado, eu estaria interessado.
Em alternativa, SQL%ROWCOUNT
você pode usar isso dentro do procedimento sem qualquer necessidade de declarar uma variável
SQL%ROWCOUNT
também pode ser usado sem ser atribuído (pelo menos a partir de Oracle 11g).
Desde que não tenha sido realizada nenhuma operação (actualizações, apagamentos ou inserções) dentro do bloco actual, SQL%ROWCOUNT
está definido como nulo. Em seguida, permanece com o número de linhas afetadas pela última operação DML:
digamos que temos um cliente de mesa
create table client (
val_cli integer
,status varchar2(10)
)
/
testá-lo-íamos assim.:
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;
resultando em:
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
Por favor, experimenta este..
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;
--------------------------------------------------------
O resultado será o seguinte:
2 Cliente actualizado para 1
nenhum cliente com 2 val_cli.
nenhum cliente com 3 val_cli.
1 cliente actualizado para 4
nenhum cliente com 5 val_cli.
1 cliente actualizado para 6
nenhum cliente com 7 val_cli.
nenhum cliente com 8 val_cli.
nenhum cliente com 9 val_cli.
1 cliente actualizado para 10
Número total de linhas afectadas Operação de actualização: 5
Usar a função analítica Contagem (*) sobre a partição por NULL Isto contará o total # de linhas