2009-05-14 20 views
124

Ho una funzione PL/SQL (in esecuzione su Oracle 10g) in cui aggiorno alcune righe. C'è un modo per scoprire quante righe sono state interessate da UPDATE? Quando eseguo manualmente la query mi dice quante righe sono state interessate, voglio ottenere quel numero in PL/SQL.Numero di righe interessate da un UPDATE in PL/SQL

risposta

194

Si utilizza la variabile sql%rowcount.

È necessario richiamarlo subito dopo l'istruzione per cui è necessario trovare il numero di righe interessato.

Ad esempio:

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

in alternativa, SQL%ROWCOUNT si può usare questo all'interno della procedura senza alcun bisogno di dichiarare una variabile

+3

SQL% ROWCOUNT è una funzione, non si può semplicemente "usarlo" - è necessario fare * * qualcosa con esso - se memorizzare in una variabile, o inviarlo come input ad un'altra procedura, o aggiungerlo a qualcos'altro. –

+7

Penso che il punto di Ali H sia che non è necessario assegnarlo a una variabile finché non si ha un'altra istruzione SQL che influenzi il conteggio delle righe. Detto questo, sono d'accordo che dovrebbe essere assegnato a una variabile per evitare di causare un bug in un secondo momento se qualcuno dovesse aggiungere un'altra istruzione SQL prima che venga chiamata. E, questa risposta di Ali H dovrebbe essere un commento sulla risposta di Clive piuttosto che pubblicata come risposta separata – Kirby

18

Per coloro che vogliono i risultati di un comando semplice, la soluzione potrebbe essere:

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

Il problema fondamentale è che ROWCOUNT SQL% è una variabile PL/SQL (o funzione), e non possono essere dir accessibile direttamente da un comando SQL. Usando un blocco PL/SQL noname, questo può essere ottenuto.

... Se qualcuno ha una soluzione per usarlo in un comando SELECT, sarei interessato.

-3

Utilizzare il conteggio (*) funzione analitica SOPRA PARTITION BY NULL Questo conterà il # totale di righe

+0

Dopo aver eseguito la dichiarazione di aggiornamento se si controlla il conteggio su ciò che effettivamente aggiornato - Questo non fornisce alcuna soluzione generica. Ad esempio, se la mia tabella T ha una colonna c1 che contiene "1" come valore per tutti e ora aggiorno tutte le righe per quella colonna a "2", come partizionerà per aiuto Null? – nanosoft

1

SQL%ROWCOUNT può essere utilizzato anche senza essere assegnato (almeno dal Oracle 11g).

Fintantoché nessuna operazione (aggiornamenti, eliminazioni o inserimenti) è stata eseguita all'interno del blocco corrente, SQL%ROWCOUNT è impostato su null. Poi si rimane con il numero della linea interessata dal ultima operazione DML:

dire che abbiamo tavolo CLIENTE

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

Vorremmo provare in questo modo:

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; 

Data:

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

Si prega di provare questo ..


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; 

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

risultato sarà come di seguito:


2 client aggiornato per 1
nessun cliente con 2 val_cli.
nessun client con 3 val_cli.
1 client aggiornato per 4
nessun client con 5 val_cli.
1 client aggiornato per 6
nessun client con 7 val_cli.
nessun client con 8 val_cli.
nessun client con 9 val_cli.
1 client aggiornato per il 10
Numero di linee totali operazione di aggiornamento interessata: 5


+0

Puoi per favore formattare correttamente il tuo messaggio? –

Problemi correlati