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 :

Mettre à jour toutes les colonnes d'une table avec MERGE INTO


Sujet :

SQL Oracle

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    resp. cellule urbanisation
    Inscrit en
    Juin 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : resp. cellule urbanisation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2012
    Messages : 31
    Points : 34
    Points
    34
    Par défaut Mettre à jour toutes les colonnes d'une table avec MERGE INTO
    Bonjour,

    Je viens de découvrir l’instruction SQL : MERGE INTO....
    Et là je me dis que je suis vraiment une buse de ne pas la connaitre depuis longtemps....

    J'ai juste une petite question sur son utilisation :
    faut-il obligatoirement lister toutes les colonnes dans la clause SET du UPDATE ?

    Bien sur, cette question n'a de sens que dans le cas suivant :

    j'ai deux tables ayant la même structure (une table de gestion et une table de sauvegarde) , la table de sauvegarde étant créée comme une "copie" de la table de gestion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     CREATE TABLE Tab_Sauv As Select * From Tab_Gest
    après quelques tests, qui modifient les données de la table de gestion, je voudrais remettre cette dernière dans son état initial, sans faire des DELETE suivi d' INSERT (vu le nombre de contraintes référentielles qu'il faudrait alors prendre en compte).
    J'ai donc pensé utiliser l'ordre MERGE INTO, comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Merge Into Tab_Gest TG Using Tab_Sauv TS
    On (  TG.ID = TS.ID )
    When Matched Then Update Set TG.* = TS.* Where TG.ID = TS.Id
    où les colonnes Id sont les clef primaires de chacune des tables.
    Bien entendu cette instruction est en erreur sur les * dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    When Matched Then Update Set TG.* = TS.*

  2. #2
    Expert éminent sénior 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
    Points : 11 252
    Points
    11 252

  3. #3
    Expert éminent sénior 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
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Andre.lissarrague Voir le message
    ..., je voudrais remettre cette dernière dans son état initial...
    Regardez aussi flashback table

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    resp. cellule urbanisation
    Inscrit en
    Juin 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : resp. cellule urbanisation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2012
    Messages : 31
    Points : 34
    Points
    34
    Par défaut
    Merci mnitu !

    J’avais bien vu la doc Oracle, mais j’espérai qu'il y a avait une astuce de DBA ou développeur, pour éviter de lister les 78 colonnes de mes tables .
    (mais bon avec quelques copier/coller, un tableur et traitement de texte de base, je peux générer rapidement et sans erreur, les égalités pour toutes les colonnes, quelques soit leur nombre)

    Effectivement, faut que je regarde plus en détail tout ce qui tourne autour de flashback table.
    mais j'ai bien peur, que vu la profondeur de mon historique, test sur plusieurs jours, je ne récupère pas tout.
    Par contre, pour les prochains tests se sera très utile.


    Encore merci.

    Comme quoi il est toujours bon d'avoir un point de vue extérieur.

    bonne journée.

  5. #5
    Membre expérimenté
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Points : 1 717
    Points
    1 717
    Billets dans le blog
    6
    Par défaut
    Je te propose un autre principe vu le nombre important des colonnes.
    et en terme de temps d’exécution est plus rapide ..

    tu trouves la simulation dans le fichier ci-joint
    Pièces jointes en attente de validation Pièces jointes en attente de validation
    d'avoir Pensé à voter positivement pour ceux qui vous ont aidés et surtout à mettre si le cas.
    ça encourage.

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    resp. cellule urbanisation
    Inscrit en
    Juin 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : resp. cellule urbanisation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2012
    Messages : 31
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par islamov2000 Voir le message
    Je te propose un autre principe vu le nombre important des colonnes.
    et en terme de temps d’exécution est plus rapide ..

    tu trouves la simulation dans le fichier ci-joint
    Bonjour islamov2000,

    mais j'arrive pas à télécharger ton fichier Word, ou alors je ne sais pas comment le faire .....
    Il est indiqué comme "Pièces jointes en attente de validation".
    est-ce que la vient de là ??

    D'avance merci

  7. #7
    Membre expérimenté
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Points : 1 717
    Points
    1 717
    Billets dans le blog
    6
    Par défaut
    Une simulation:
    Creation d'une table:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    create table A_Tab_Sauv  as
      select 1 Id,'a' c1,'a' c2,'a' c3,'a' c4,'a' c5,'a' c6,'a' c7,'a' c8,'a' c9,'a' c10 from dual union
      select 2 Id,'b' c1,'b' c2,'b' c3,'b' c4,'b' c5,'b' c6,'b' c7,'b' c8,'b' c9,'b' c10 from dual union
      select 3 Id,'c' c1,'c' c2,'c' c3,'c' c4,'c' c5,'c' c6,'c' c7,'c' c8,'c' c9,'c' c10 from dual union
      select 4 Id,'d' c1,'d' c2,'d' c3,'d' c4,'d' c5,'d' c6,'d' c7,'d' c8,'d' c9,'d' c10 from dual union
      select 5 Id,'e' c1,'e' c2,'e' c3,'e' c4,'e' c5,'e' c6,'e' c7,'e' c8,'e' c9,'e' c10 from dual union
      select 6 Id,'f' c1,'f' c2,'f' c3,'f' c4,'f' c5,'f' c6,'f' c7,'f' c8,'f' c9,'f' c10 from dual union
      select 7 Id,'g' c1,'g' c2,'g' c3,'g' c4,'g' c5,'g' c6,'g' c7,'g' c8,'g' c9,'g' c10 from dual union
      select 8 Id,'h' c1,'h' c2,'h' c3,'h' c4,'h' c5,'h' c6,'h' c7,'h' c8,'h' c9,'h' c10 from dual union
      select 9 Id,'i' c1,'i' c2,'i' c3,'i' c4,'i' c5,'i' c6,'i' c7,'i' c8,'i' c9,'i' c10 from dual union
      select 10 Id,'j' c1,'j' c2,'j' c3,'j' c4,'j' c5,'j' c6,'j' c7,'j' c8,'j' c9,'j' c10 from dual;

    Sauvegarder
    la table:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    create table  A_Tab_Gest as
      (select * from A_Tab_Sauv);--
    Modifier quelques lignes de la table A_Tab_Gest:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    update A_Tab_Gest set c1='z' where id=1;
      update A_Tab_Gest set c4='y' where id=5;
      update A_Tab_Gest set c8='x' where id=6;
      update A_Tab_Gest set c2='w' where id=10;






    Récupération des données modifiées

    *Supprimer les ligne modifiées

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    delete from A_Tab_Gest A
      where A.id in (select B.id from (select   * from A_Tab_Gest Tg
      minus
      select * from A_Tab_Sauv TS)B);
    *Insérer les lignes de la source:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    insert iinto A_Tab_Gest 
      select * from A_Tab_Sauv TS
      minus
      select * from A_Tab_Gest Tg;
    d'avoir Pensé à voter positivement pour ceux qui vous ont aidés et surtout à mettre si le cas.
    ça encourage.

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    resp. cellule urbanisation
    Inscrit en
    Juin 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : resp. cellule urbanisation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2012
    Messages : 31
    Points : 34
    Points
    34
    Par défaut
    Merci beaucoup islamov2000.

    Effectivement en terme d'écriture c'est super efficace, et le principe super simple.

    Le petit inconvénient mais qui peut facilement se contourner est la gestion des contraintes référentielles.
    En effet dans ton script on fait que des DELETE et INSERT, un enregistrement déjà existant mais modifié, est d'abord supprimé pour être recréé dans sa version original, ce qui peut mettre à mal des clés étrangères des autres tables pointant sur cet enregistrement.
    Le contournement est de désactiver toutes les contraintes avant la manip. sans oublier de les réactivées après.

    Cela dit, dans le cas d’utilisation de la commande MERGE INTO, on peut avoir le même soucis, si une des valeurs modifiées est utilisée comme clé étrangère dans une autre table.
    Ces cas sont généralement moins nombreux, cela veut dire que l'on a modifié plusieurs tables (relativement courant dans un SGBDR de gestion), et donc la restauration dans l'état initial nécessite de faire la manip sur plusieurs tables. Du coup ont bien obligé de désactiver les contraintes quelle que soit la méthode choisie, à moins d'écrire un beau script PL/SQL (mais c'est justement ce que l'on voulait éviter).

    En tout en grand merci à islamov2000 & à mnitu.

    PS . Si pas de nouveaux message d'ici une semaine, je clôturerais la discussion.

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Citation Envoyé par Andre.lissarrague Voir le message
    En effet dans ton script on fait que des DELETE et INSERT, un enregistrement déjà existant mais modifié, est d'abord supprimé pour être recréé dans sa version original, ce qui peut mettre à mal des clés étrangères des autres tables pointant sur cet enregistrement.
    Le contournement est de désactiver toutes les contraintes avant la manip. sans oublier de les réactivées après.
    Vous pouvez aussi utiliser des contraintes reportables.
    Elles ne seront validées qu'à la fin de la transaction.

    http://docs.oracle.com/cd/E11882_01/....htm#CNCPT1646
    http://docs.oracle.com/cd/B19306_01/...2.htm#i1015767

    Pour le merge, vous pouvez générer le script en construisant la requête sur les tables systèmes all_tab_columns, par exemple.

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    resp. cellule urbanisation
    Inscrit en
    Juin 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : resp. cellule urbanisation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2012
    Messages : 31
    Points : 34
    Points
    34
    Par défaut
    Merci à tous !

    J'en ai appris pas mal grâce à vous....(l'aspect reportable des contraintes, flashback, etc.).

    Je conclus la discussion afin de ne pas la laisser indéfiniment ouverte.

    et encore un grand merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Mettre à jour toutes les lignes d'une table
    Par huzard dans le forum MySQL
    Réponses: 6
    Dernier message: 25/02/2015, 19h05
  2. Réponses: 4
    Dernier message: 04/10/2010, 19h01
  3. nom de toutes les colonnes d'une table
    Par jeorcal dans le forum Langage SQL
    Réponses: 2
    Dernier message: 03/07/2010, 22h31
  4. Recherche sur toutes les colonnes d'une table
    Par Romain_marine dans le forum Requêtes
    Réponses: 2
    Dernier message: 02/04/2010, 14h35
  5. Réponses: 6
    Dernier message: 01/08/2006, 18h12

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