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

Oracle Discussion :

[Oracle 9] Contrainte d'intégrité référentielle sur 2 tables


Sujet :

Oracle

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 45
    Points : 37
    Points
    37
    Par défaut [Oracle 9] Contrainte d'intégrité référentielle sur 2 tables
    Bonjour,

    Est-il possible, en SQL standard, ou bien sur Oracle 9, de définir une foreign key sur 2 tables. C'est-à-dire indiquer que la clé étrangère doit appartenir à une table OU a l'autre. Par exemple si j'ai une table "maison", une table "appartement" et une table "personne", et que chaque personne a soit une maison, soit un appartement, la table "personne" doit avoir un lien vers l'une des 2 tables (mais pas les 2).
    Est-il possible de le faire sans définir une table temporaire qui réunisse les 2 ?
    Ou bien si je définis une vue qui fasse l'union des 2, puis-je définir une contrainte d'intégrité vers la vue ?

    Merci

  2. #2
    Membre confirmé

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    bonjour,

    Je ne pense pas que cela soit possible.
    Dans ce genre de cas, il faut modéliser un héritage (en tout cas, c'est le genre de technique que j'utilise).
    Tu crées une table habitation dans laquelle tu met l'union de tes deux tables (au moins la pk). Cela implique évidement la même pk.
    Tu peux maintenir facilement ta table d'habitation avec un trigger pour chaque table fille

  3. #3
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Et pourquoi pas mettre tes 2 clés étrangères dans la table personnes ?

  4. #4
    Membre confirmé

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    Citation Envoyé par sygale
    Et pourquoi pas mettre tes 2 clés étrangères dans la table personnes ?
    cette solution implique d'avoir trois colonnes dans la table personne.
    Une première pour les adresses "maison"
    Une deuxième pour les adresses 'appartement"
    et une troisième avec un flag maison appartement.
    Il faut bien voir ensuite à ce qu'une ees deux colonnes soit toujours vide.


    Personnellement, si on veux regrouper l'information, je n'aime pas trop.
    L'idée est de dire qu'une personne à une habitation et l'héritage semble nien adapté ici

  5. #5
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Citation Envoyé par aline
    cette solution implique d'avoir trois colonnes dans la table personne.
    Une première pour les adresses "maison"
    Une deuxième pour les adresses 'appartement"
    et une troisième avec un flag maison appartement.
    Il faut bien voir ensuite à ce qu'une ees deux colonnes soit toujours vide.
    Je ne suis pas d'accord, 2 champs suffisent et une contrainte de type check

    exemple

    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
    SQL>create table table1(id char(1),app char(1),mai char(1));
     
    Table créée.
     
    Ecoulé : 00 :00 :00.00
    SQL>alter table table1 add (constraint chk_app_mai
      2   check ((mai is not null and app is null)  or  (app is not null and mai is null)));
     
    Table modifiée.
     
    Ecoulé : 00 :00 :00.00
    SQL>insert into table1(id,app,mai) values('A','A',null);
     
    1 ligne créée.
     
    Ecoulé : 00 :00 :00.00
    SQL>insert into table1(id,app,mai) values('B',null,'B');
     
    1 ligne créée.
     
    Ecoulé : 00 :00 :00.00
    SQL>insert into table1(id,app,mai) values('C','C','C');
    insert into table1(id,app,mai) values('C','C','C')
    *
    ERREUR à la ligne 1 :
    ORA-02290: violation de contraintes (ETOILE.CHK_APP_MAI) de vérification
     
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from table1;
    I A M
    - - -
    A A ¤
    B ¤ B
     
    Ecoulé : 00 :00 :00.00
    SQL>
    Il reste plus qu'a mettre les contraintes Foreign key et cela devrait fonctionner non ?

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 45
    Points : 37
    Points
    37
    Par défaut
    Merci pour vos réponses.
    J'espérais que Oracle propose une fonctionnalité qui permette une référence (A ou B), même si ce n'est pas du SQL standard. Apparemment ce n'est pas le cas.
    Je pense m'inspirer de ces réponses, en utilisant la table de liens :
    A B
    1 x 1
    2 2 x
    3 3 x
    ...
    et utiliser des triggers pour remplir automatiquement la table de liens lors d'une insertion dans une des deux tables.

  7. #7
    Membre confirmé

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    Bonjour sygale,

    Excuse moi si ma réponse semblait un peut stricte. Faire deux colonnes et pointer sur les deux tables est tout à fait possible et ta solution est juste. Je disais juste que je n'aime pas trop pointer sur les deux tables.
    Mais techniquement c'est en effet tout à fait faisable.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 45
    Points : 37
    Points
    37
    Par défaut
    Sinon je pensais que la solution la plus simple consistait à ne pas définir de contrainte sur ma table personne, mais à créer un trigger qui vérifie que les données modifiées/insérées sont bien présentes dans l'une ou l'autre des tables.
    Cependant, je me demande si cette solution ne peut pas poser de problème de temps de calcul en cas d'insertion ou de suppression de plusieurs centaines de milliers de tuples en une seule requête, car le trigger serait appelé pour chaque tuple.

  9. #9
    Membre confirmé

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    Citation Envoyé par doukem
    Sinon je pensais que la solution la plus simple consistait à ne pas définir de contrainte sur ma table personne, mais à créer un trigger qui vérifie que les données modifiées/insérées sont bien présentes dans l'une ou l'autre des tables.
    Bonjour,

    Prends une des deux solutions dont nous avons débattus. Par contre, le trigger pour verifier une integrité quelconque ne me parait techniquement pas approprié.

    Par exemlple, si dans une session tu crée un utilisteur avec une adresse, le check de l'integrité se fait au moment ou tu commence ta transaction. Si entre-temps quelqu'un supprime ton addresse dans une autre session avant que tu ne commites (il ne voit donc pas ton addresse et ces checks ne fonctionneront pas!), tu risques d'avoir un gros problème.
    Le triggers ne sont pas faits gérer les contraintes de ce type à mon goût.

  10. #10
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Citation Envoyé par aline
    Bonjour sygale,
    Excuse moi si ma réponse semblait un peut stricte.
    Aucun mal, nous sommes pas forcé d'être d'accord et c'est tout l'intérêt du forum, plusieurs solutions à un problème permet de former tout le monde aussi !

    De plus ton aide et les notes de ton profil prouve que tu es un membre de valeur

  11. #11
    Membre régulier Avatar de links
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 113
    Points : 95
    Points
    95
    Par défaut
    bonjour,
    juste une remarque, il faut savoir que la foreigne key pointe vers une unique key, la valeur pointé peut etre nulle

Discussions similaires

  1. Réponses: 0
    Dernier message: 30/12/2011, 15h00
  2. Phpmyadmin et contraintes d'intégrité référentielle ?
    Par Jiraiya42 dans le forum Requêtes
    Réponses: 28
    Dernier message: 22/02/2008, 10h31
  3. Réponses: 4
    Dernier message: 12/12/2007, 15h12
  4. Réponses: 5
    Dernier message: 26/10/2005, 14h43
  5. [debutant] Contraintes d'intégrité définies sur un objet
    Par maysa dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 25/05/2004, 14h57

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