2009-05-14 16 views
124

Tengo una función PL/SQL (ejecutándose en Oracle 10g) en la que actualizo algunas filas. ¿Hay alguna manera de averiguar cuántas filas se vieron afectadas por la ACTUALIZACIÓN? Al ejecutar la consulta manualmente, me dice cuántas filas se vieron afectadas, quiero obtener ese número en PL/SQL.Número de filas afectadas por una ACTUALIZACIÓN en PL/SQL

Respuesta

194

Utiliza la variable sql%rowcount.

Debe llamarlo directamente después de la instrucción para la que necesita encontrar el recuento de filas afectadas.

Por ejemplo:

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

alternativamente, SQL%ROWCOUNT Puede utilizar esta dentro del procedimiento sin necesidad de declarar una variable

+3

SQL% ROWCOUNT es una función, no se puede simplemente "usarlo" - que necesita para hacer * * algo con él - ya sea almacenar en una variable, o enviarla como entrada a otro procedimiento, o agregarla a otra cosa. –

+7

Creo que el punto de Ali H es que no es necesario asignarlo a una variable hasta que tenga otra instrucción SQL que afecte el recuento de filas. Dicho esto, acepto que se debe asignar a una variable para evitar causar un error más adelante si alguien agregara otra instrucción SQL antes de que se llame. Y esta respuesta de Ali H debería ser un comentario sobre la respuesta de Clive en lugar de publicada como una respuesta separada – Kirby

18

Para aquellos que quieren los resultados de un comando sencillo, la solución podría sea:

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

El problema básico es que SQL% ROWCOUNT es una variable PL/SQL (o función), y no puede ser dir ectly accedido desde un comando SQL. Al usar un bloque PL/SQL noname, esto se puede lograr.

... Si alguien tiene una solución para usarlo en un comando SELECCIONAR, me interesaría.

-3

Usar la cuenta (*) función analítica MÁS DE REPARTO POR NULL Este contará el # total de filas

+0

Después de ejecutar la declaración de actualización si verifica el recuento de lo que realmente actualizó: esto no ofrece ninguna solución genérica. Por ejemplo, si mi tabla T tiene una columna c1 que contiene "1" como valor para todos y ahora actualizo todas las filas para esa columna a "2", ¿cómo funcionará la partición por nulo? – nanosoft

1

SQL%ROWCOUNT también se puede utilizar sin ser asignado (al menos desde Oracle 11g).

Mientras no se haya realizado ninguna operación (actualizaciones, eliminaciones o inserciones) dentro del bloque actual, SQL%ROWCOUNT se establece en nulo. A continuación, se queda con el número de la línea afectada por la última operación DML:

decir que tenemos CLIENTE mesa

create table client (
    val_cli integer 
,status varchar2(10) 
) 
/

Nos gustaría probar de esta manera:

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 en:

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 
0

Por favor, intente éste ..


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; 

-------------------------------------------------------- 

El resultado será como a continuación:

cliente

2 actualizado para 1
ningún cliente con 2 val_cli.
sin cliente con 3 val_cli.
1 cliente actualizado para 4
ningún cliente con 5 val_cli.
1 cliente actualizado para 6
ningún cliente con 7 val_cli.
sin cliente con 8 val_cli.
sin cliente con 9 val_cli.
1 cliente actualiza durante 10
Número total de líneas afectada operación de actualización: 5


+0

¿Puedes formatear tu mensaje correctamente? –

Cuestiones relacionadas