IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

clause where current of


Sujet :

SQL Oracle

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    988
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 988
    Par défaut clause where current of
    Bonjour,

    D'après ce que j'ai compris de cette clause, elle permet de mettre à jour ou de supprimer l'enregistrement courant.
    Mais en quoi est elle vraiement utile, car si j'ai bien compris, le traitement au niveau d'un curseur se fait toujours ligne par ligne, donc l'instruction update ou DELETE utilisée aurait de toute manière concerné l'enresgitrement courant.

    Merci de votre aide.
    Cordialement.
    Nathamlie

  2. #2
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Il doit y avoir une gestion particulière de la mise à jour :
    exemple Table TCLIENT pk (ste, client)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    cursor c is select rowid, ste, client, nom from TCLIENT for update;
    BEGIN
    FOR r IN c
    LOOP
     update TCLIENT set nom = 'A' WHERE ste = r.ste AND client = r.client;
     update TCLIENT set nom = 'A' WHERE rowid = r.rowid;
     update TCLIENT set nom = 'A' WHERE current of c;
    END LOOP;
    END;
    Ces 3 updates ont le même résultat, mais dans les 2 premiers, je pense qu'Oracle doit refaire une recherche contrairement au current of.

  3. #3
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Les différences sont liées plutôt à la gestion des verrous et des transactions. Pour utiliser « current of » le curseur doit être ouverte avec la clause « for update » ce qui va entraîner le verrouillage des enregistrements de l’ouverture du curseur. Après commit il n’est plus possible de faire le fetch sauf à re ouvrir le curseur. Par contre les versions avec clé primaire/unique ou rowid peuvent être employés après commit. La mise à jour avec rowid ou current of doit avoir des performances similaires.

  4. #4
    Membre expérimenté Avatar de DAB.cz
    Inscrit en
    Octobre 2006
    Messages
    221
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 221
    Par défaut
    J'étais curieux de savoir, ce qui serait arrivé avec deux tables dans FROM:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    declare
      cursor c IS SELECT ta.a, ta.b FROM ta, tb where ta.a = tb.a  FOR UPDATE;
    BEGIN
      FOR r IN c LOOP
       UPDATE ta SET b = 1 WHERE current of c;
       dbms_output.put_line (to_char (sql%rowcount));
      END LOOP;
    END;
    /
     
    0
    0
    Aucune erreur (ORA-xxxxx), pourquoi?

    Ca marche bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    declare
      cursor c IS SELECT ta.a, ta.b FROM ta
        where exists (select 1 from tb where ta.a = tb.a)  FOR UPDATE;
    BEGIN
      FOR r IN c LOOP
       UPDATE ta SET b = 1 WHERE current of c;
       dbms_output.put_line (to_char (sql%rowcount));
      END LOOP;
    END;
    /
     
    1
    1
    DAB

  5. #5
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Pas de mise à jour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    declare
      cursor c is select ename, dname from scott.emp e, scott.dept d where e.deptno = d.deptno for update;
      l_ename  scott.emp.ename%type;
      l_dname  scott.dept.dname%type;
    begin
      open c;
      fetch c into l_ename, l_dname;
      update scott.emp set ename = l_ename where current of c;
      dbms_output.put_line('EMP -> '||To_Char(sql%rowcount));
      update scott.dept set dname = l_dname where current of c;
      dbms_output.put_line('DEPT -> '||To_Char(sql%rowcount));
      rollback;
    end;
    /
    EMP -> 0
    DEPT -> 0
    mais les deux tables dont verrouillés.

    Par contre il y a erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    declare
      cursor c is select ename, dname from scott.emp e, scott.dept d where e.deptno = d.deptno for update of e.ename;
      l_ename  scott.emp.ename%type;
      l_dname  scott.dept.dname%type;
    begin
      open c;
      fetch c into l_ename, l_dname;
      update scott.emp set ename = l_ename where current of c;
      dbms_output.put_line('EMP -> '||To_Char(sql%rowcount));
      update scott.dept set dname = l_dname where current of c;
      dbms_output.put_line('DEPT -> '||To_Char(sql%rowcount));
      rollback;
    end;
    /
    EMP -> 1
    declare
    *
    ERREUR Ó la ligne 1 :
    ORA-01410: ROWID non valide
    ORA-06512: Ó ligne 10
    Sinon la bière est-il toujours aussi bonne DAB.cz ?

  6. #6
    Membre expérimenté Avatar de DAB.cz
    Inscrit en
    Octobre 2006
    Messages
    221
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 221
    Par défaut
    toujours les nouveautés pour moi: Ora docs.

    Citation Envoyé par mnitu Voir le message
    Sinon la bière est-il toujours aussi bonne DAB.cz ?
    Même meilleur q'autrefois.

Discussions similaires

  1. Curseur et clause WHERE CURRENT OF
    Par mystia dans le forum Oracle
    Réponses: 3
    Dernier message: 14/03/2006, 18h14
  2. Ordre des tests dans la clause WHERE
    Par Tans98 dans le forum Langage SQL
    Réponses: 6
    Dernier message: 22/09/2004, 10h52
  3. Problème clause WHERE
    Par Invité dans le forum Langage SQL
    Réponses: 3
    Dernier message: 11/06/2004, 15h07
  4. probleme avec le caractere 'Z' dans ma clause WHERE
    Par dibox dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/04/2004, 12h21
  5. [ character en simple cote ] clause Where
    Par hocinema dans le forum DB2
    Réponses: 3
    Dernier message: 20/02/2004, 10h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo