2009-05-14 4 views
124

J'ai une fonction PL/SQL (exécutée sur Oracle 10g) dans laquelle je mets à jour certaines lignes. Existe-t-il un moyen de savoir combien de lignes ont été affectées par la mise à jour? Lors de l'exécution de la requête manuellement, il me dit combien de lignes ont été affectées, je veux obtenir ce nombre en PL/SQL.Nombre de lignes affectées par une UPDATE en PL/SQL

Répondre

194

Vous utilisez la variable sql%rowcount.

Vous devez l'appeler directement après l'instruction dont vous avez besoin pour trouver le nombre de lignes affecté.

Par exemple:

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

alternativement, SQL%ROWCOUNT vous pouvez utiliser cela dans la procédure sans qu'il soit nécessaire de déclarer une variable

+3

SQL% ROWCOUNT est une fonction, vous ne pouvez pas « utiliser » - vous devez * faire * quelque chose avec - soit stocker dans une variable, ou l'envoyer en entrée à une autre procédure, ou l'ajouter à autre chose. –

+7

Je pense que le point de Ali H est qu'il n'est pas nécessaire de l'assigner à une variable jusqu'à ce que vous ayez une autre instruction SQL qui affecterait le nombre de lignes. Cela étant dit, je suis d'accord qu'il devrait être affecté à une variable pour éviter de causer un bogue plus tard si quelqu'un ajoute une autre instruction SQL avant d'être appelée. Et, cette réponse d'Ali H devrait être un commentaire sur la réponse de Clive plutôt que de la publier comme une réponse séparée – Kirby

18

Pour ceux qui veulent les résultats d'une commande simple, la solution pourrait soit:

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

Le problème fondamental est que ROWCOUNT SQL% est une variable PL/SQL (ou la fonction) et ne peut pas être dir ectly accessible à partir d'une commande SQL. En utilisant un bloc PL/SQL noname, ceci peut être réalisé.

... Si quelqu'un a une solution pour l'utiliser dans une commande SELECT, je serais intéressé.

-3

Utilisez le COUNT (*) fonction analytique SUR PARTITION BY NULL Ce comptera le # total de lignes

+0

Après l'exécution de l'instruction update si vous vérifiez le décompte de ce que vous avez réellement mis à jour - Cela ne donne aucune solution générique. Par exemple, si ma table T a une colonne c1 qui contient "1" comme valeur pour tous et maintenant je mets à jour toutes les lignes pour cette colonne à "2", comment le partitionnement par null aidera-t-il? – nanosoft

1

SQL%ROWCOUNT peut également être utilisé sans être affecté (au moins de Oracle 11g).

Tant qu'aucune opération (mises à jour, suppressions ou insertions) n'a été effectuée dans le bloc actuel, SQL%ROWCOUNT est défini sur null. Ensuite, il reste avec le nombre de lignes affectées par la dernière opération DML:

dire que nous avons la table CLIENT

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

Nous tester cette façon:

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; 

Résultats:

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

S'il vous plaît essayer celui-ci ..


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; 

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

Le résultat sera comme ci-dessous:


2 client mis à jour pour 1
pas client 2 val_cli.
aucun client avec 3 val_cli.
1 client mis à jour pour 4
aucun client avec 5 val_cli.
1 client mis à jour pour 6
aucun client avec 7 val_cli.
aucun client avec 8 val_cli.
aucun client avec 9 val_cli.
1 client mis à jour pour 10
Nombre total de lignes d'opération de mise à jour affectée: 5


+0

Pouvez-vous s'il vous plaît formater votre message correctement? –

Questions connexes