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 :

Mise à jour d'une table à partir d'une autre


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut Mise à jour d'une table à partir d'une autre
    Bonjour,

    Comme mon MERGE ne fonctionne pas, j'essaie par un traditionnel UPDATE...

    Je dois donc mettre à jour ma table actuelle GRHUM.TYPE_POPULATION à partir d'une table de référence identique que j'ai stockée dans mon schéma PLEMENAGER.TYPE_POPULATION.

    Les deux tables font 31 lignes.

    La requête suivante me dit que j'ai 4 lignes à mettre à 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
    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
    SELECT *
    FROM PLEMENAGER.TYPE_POPULATION rf
    WHERE NOT EXISTS
    (
      SELECT *
      FROM GRHUM.TYPE_POPULATION act
      WHERE act.C_TYPE_POPULATION = rf.C_TYPE_POPULATION
        AND act.LC_TYPE_POPULATION = rf.LC_TYPE_POPULATION
        AND act.LL_TYPE_POPULATION = rf.LL_TYPE_POPULATION
        AND (
            CASE 
                WHEN act.REF_REGLEMENTAIRE IS NULL AND rf.REF_REGLEMENTAIRE IS NULL THEN 1 
                WHEN act.REF_REGLEMENTAIRE = rf.REF_REGLEMENTAIRE THEN 1
                ELSE 0 
            END
        ) = 1
        AND act.TEM_FONCTIONNAIRE = rf.TEM_FONCTIONNAIRE
        AND act.TEM_ATOS = rf.TEM_ATOS
        AND act.TEM_ITARF = rf.TEM_ITARF
        AND act.TEM_ENS_SUP = rf.TEM_ENS_SUP
        AND act.TEM_ENSEIGNANT = rf.TEM_ENSEIGNANT
        AND act.TEM_2DEGRE = rf.TEM_2DEGRE
        AND act.TEM_HOSPITALIER = rf.TEM_HOSPITALIER
        AND act.TEM_BIBLIO = rf.TEM_BIBLIO
        AND act.TEM_CARRIERE = rf.TEM_CARRIERE
        AND TO_CHAR(act.D_CREATION) = TO_CHAR(rf.D_CREATION)
        AND TO_CHAR(act.D_MODIFICATION) = TO_CHAR(rf.D_MODIFICATION)
        AND act.TEM_1DEGRE = rf.TEM_1DEGRE
        AND act.TEM_VISIBLE = rf.TEM_VISIBLE
        AND 
        (
            CASE 
                WHEN act.D_OUVERTURE IS NULL AND rf.D_OUVERTURE IS NULL THEN 1 
                WHEN TO_CHAR(act.D_OUVERTURE) = TO_CHAR(rf.D_OUVERTURE) THEN 1
                ELSE 0 
            END
        ) = 1
        AND 
        (
            CASE 
                WHEN act.D_FERMETURE IS NULL AND rf.D_FERMETURE IS NULL THEN 1 
                WHEN TO_CHAR(act.D_FERMETURE) = TO_CHAR(rf.D_FERMETURE) THEN 1
                ELSE 0 
            END
        ) = 1
    )
    ORDER BY rf.C_TYPE_POPULATION
    Comme l'examen de cette petite table m'a permis de découvrir que les différences portent surtout sur un détail de dates, j'ai commencé à construire la requête suivante qui met bien les lignes à jour mais que je trouve déjà bien compliquée :
    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
    UPDATE GRHUM.TYPE_POPULATION act
    SET 
    	act.D_CREATION = (
    	SELECT D_CREATION
    	FROM PLEMENAGER.TYPE_POPULATION rf
    	WHERE rf.C_TYPE_POPULATION = act.C_TYPE_POPULATION
    		AND act.C_TYPE_POPULATION IN ('AM', 'DF', 'MF', 'SF') 
    	),
    	act.D_MODIFICATION = (
    	SELECT D_MODIFICATION
    	FROM PLEMENAGER.TYPE_POPULATION rf
    	WHERE rf.C_TYPE_POPULATION = act.C_TYPE_POPULATION
    		AND act.C_TYPE_POPULATION IN ('AM', 'DF', 'MF', 'SF') 
    	)
    	-- idem pour chaque colonne
    WHERE EXISTS (
    	SELECT *
    	FROM PLEMENAGER.TYPE_POPULATION rf1
    	WHERE rf1.C_TYPE_POPULATION = act.C_TYPE_POPULATION
    		AND rf1.C_TYPE_POPULATION IN ('AM', 'DF', 'MF', 'SF')
    );
    Le "-- idem pour chaque colonne" signifie que, dans l'absolu, je devrais avoir le même genre de code avec une sous-requête pour chaque colonne de la table.

    Y a t-il une requête plus simple et plus générale pour faire cette sorte de mise à jour car j'aurai d'autres tables à traiter et potentiellement avec beaucoup plus de lignes donc impossible de "voir" facilement ce qu'il faut mettre à jour ? Et la quantité de lignes à mettre à jour risque aussi d'être beaucoup plus grand, ce qui complique encore les IN de la requête.

    Serait-il par exemple possible de faire ce genre de truc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SET (col1, col2, col3) = (
        SELECT col1, col2, col3
        FROM -- ...
    )
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    TO_CHAR(act.D_CREATION) = TO_CHAR(rf.D_CREATION)
    On n'utilise jamais, mais alors jamais les fonctions to_char et to_date sans format.
    Vous venez de coder un bug.

    Citation Envoyé par CinePhil Voir le message
    Serait-il par exemple possible de faire ce genre de truc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SET (col1, col2, col3) = (
        SELECT col1, col2, col3
        FROM -- ...
    )
    Oui, ça fonctionne très bien.

Discussions similaires

  1. Réponses: 4
    Dernier message: 25/08/2015, 16h56
  2. Réponses: 7
    Dernier message: 22/06/2012, 12h12
  3. Réponses: 5
    Dernier message: 19/03/2008, 10h41
  4. [Tables] Update d'une table à partir d'une autre
    Par le_niak dans le forum VBA Access
    Réponses: 2
    Dernier message: 17/01/2008, 09h01
  5. copie d'une table Y d'une base A vers une table X d'une base
    Par moneyboss dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 30/08/2005, 21h24

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