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

PL/SQL Oracle Discussion :

mise à jour d'un champ "numérotation"


Sujet :

PL/SQL Oracle

  1. #1
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 120
    Par défaut mise à jour d'un champ "numérotation"
    Bonjour à tous,
    J'aimerais numéroter les enregistrements d'une table dans un champ NumLigne selon d'autres champs de ma table. Pourriez-vous m'aider à écrire le code permettant de faire cela ?
    Pour info, je l'ai écrit en VBA Access mais je n'ai aucune idée pour l'écrire en PL/SQL...

    Merci beaucoup,

    MarieO

    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
     
    "Ma table d'origine:"
    CHAMP1, CHAMP2, CHAMP3, NUMLIGNE
    1, 1, A, null
    1, 1, A, null
    1, 1, B, null
    1, 2, A, null
    2, 1, A, null
     
    "Ce que j'aimerais avoir après mise à jour des données"
    CHAMP1, CHAMP2, CHAMP3, NUMLIGNE
    1, 1, A, 1
    1, 1, A, 2
    1, 1, B, 1
    1, 2, A, 1
    2, 1, A, 1
    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
     
    Public Sub UpdateNumLigne
        Dim rsCompte as Dao.recordset
        Dim rsTable as Dao.recordset
        Dim i as long
     
        Set rsCompte = Currentdb.openrecordset ("SELECT Champ1, Champ2, Champ3, count(*) as Compte FROM tatable GROUP BY Champ1, Champ2, Champ3")
        Set rsTable  = currentdb.openrecordset ("SELECT * FROM tatable")
     
        While not rsCompte.EOF
            for i=1 to rsCompte.fields("Compte")
                rsTable.findfirst "Champ1=" &rsCompte.fields("Champ1") &" AND Champ2=" &rsCompte.fields("Champ2") &" AND Champ3='" &rsCompte.fields("Champ3") &"' AND Numligne is null"
                rsTable.edit
                rsTable!NumLigne = i
                rsTable.update
           next i
           rsCompte.movenext
       Wend
       rsCompte.close
       rsTable.close
    End Sub

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    507
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 507
    Par défaut
    Bonjour.
    N'avez-vous pas de clé primaire sur la table? Sans cela, vous allez devoir utiliser le ROWID. (je ne vois pas d'autre solution)

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 120
    Par défaut
    Malheureusement non, avant la numérotation des lignes, il n'y a pas de clé primaire sur la table.
    Le but de cette numérotation est de pouvoir créer une clé à partir des champs existants + celui de numérotation de ligne...

    MarieO

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Par défaut
    Bonjour,

    vous pourrez "numéroter" vos lignes en utilisant row_number() over (partition by ... order by ...).
    Comme l'a dit Goldoz, rowid permettra de différencier vos lignes identiques lors de l'update :
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    SQL> DROP TABLE test;
     
    Table supprimée.
     
    SQL> create table test
      2  as
      3  (
      4        SELECT 1 as col1, 1 as col2, 'A' as col3, cast(NULL AS NUMBER) as NumLigne from dual
      5        union all
      6        select 1, 1, 'A', NULL from dual
      7        union all
      8        select 1, 1, 'B', NULL from dual
      9        union all
     10        select 1, 2, 'A', NULL from dual
     11        union all
     12        select 2, 1, 'A', NULL from dual
     13  ); 
     
    Table créée.
     
    SQL> select * from test;
     
          COL1       COL2  COL3   NUMLIGNE
    ---------- ---------- ----- ----------
             1          1     A
             1          1     A
             1          1     B
             1          2     A
             2          1     A
     
    SQL> update test t1 
      2  set NumLigne = 
      3    (
      4      select t2.NumLigne
      5      from 
      6      (
      7        select row_number() over (partition by col1, col2, col3 order by col1, col2, col3) as NumLigne
      8        FROM test
      9      ) t2
     10      where t2.rowid = t1.rowid
     11    );
     
    5 ligne(s) mise(s) à jour.
     
    SQL> select * from test;
     
          COL1       COL2  COL3   NUMLIGNE
    ---------- ---------- ----- ----------
             1          1     A          1
             1          1     A          2
             1          1     B          1
             1          2     A          1
             2          1     A          1
    En passant, pourquoi ne pas créer un ID pour clé primaire, plutôt qu'une clé composée de la totalité des colonnes? Ca semblerait plus propre.

  5. #5
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 120
    Par défaut
    merci bcp pour ce code. Je teste tout de suite...

    Pour la création d'un ID, je n'y avais pas pensé... Comment faire pour la création de cet ID, sachant que je peux être amenée à supprimer des enregistrements de ma table puis à en ajouter d'autres en remplacement assez régulièrement et que je risque de travailler sur des milliers (voire des millions) de lignes ?

    Merci beaucoup,
    MarieO

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    507
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 507
    Par défaut
    Citation Envoyé par marieo Voir le message
    merci bcp pour ce code. Je teste tout de suite...

    Pour la création d'un ID, je n'y avais pas pensé... Comment faire pour la création de cet ID, sachant que je peux être amenée à supprimer des enregistrements de ma table puis à en ajouter d'autres en remplacement assez régulièrement et que je risque de travailler sur des milliers (voire des millions) de lignes ?

    Merci beaucoup,
    MarieO
    Vous créez une colonne "ID", NUMBER NOT NULL, une séquence, et un trigger qui renseigne automatiquement cette colonne avec la séquence.

    Une précision fonctionnelle: habituellement, un ID est unique, et si la ligne est supprimée, cet ID ne sera pas réutilisé pour une autre ligne.

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Par défaut
    Pour Oracle, on utilise des séquences :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CREATE SEQUENCE SQ_TEST 
    INCREMENT BY 1 
    START WITH 1;
    A l'insertion, on utilisera SQ_TEST.nextval comme valeur pour l'id :
    Edit : comme Goldoz le suggère, on peut définir un trigger pour le faire automatiquement.
    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
     
    SQL> update test t1 
      2  set ID = SQ_TEST.nextval;
     
    5 ligne(s) mise(s) à jour.
     
    SQL> select * from test;
     
          COL1       COL2  COL3         ID
    ---------- ---------- ----- ----------
             1          1     A          1
             1          1     A          2
             1          1     B          3
             1          2     A          4
             2          1     A          5
    La prochaine valeur de la séquence sera 6 :
    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
     
    SQL> insert into test (col1,col2,col3,id)
      2  values (3,2,'C',sq_test.nextval);
     
    1 ligne créée.
     
    SQL> select * from test;
     
          COL1       COL2  COL3         ID
    ---------- ---------- ----- ----------
             1          1     A          1
             1          1     A          2
             1          1     B          3
             1          2     A          4
             2          1     A          5
             3          2     C          6
     
    6 ligne(s) sélectionnée(s).
    Un ID n'a pas de notion d'ordre, c'est simplement un identifiant unique pour votre ligne, les suppression/insertions ne sont donc pas un problème.

    Je doute que vous ayez réellement besoin d'une colonne pour numéroter vos lignes, vous pourrez le faire dans votre requête lors de l'affichage, en fonction du besoin.

Discussions similaires

  1. [AC-2003] mise à jour d'un champ de numérotation
    Par marieo dans le forum VBA Access
    Réponses: 2
    Dernier message: 04/09/2009, 13h45
  2. mise à jour automatique de champs entre 2 tables
    Par romdyane dans le forum Access
    Réponses: 5
    Dernier message: 11/10/2005, 18h51
  3. Réponses: 2
    Dernier message: 12/02/2003, 15h26

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