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 :

Créer une contrainte d'unicité évoluée


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 114
    Points : 70
    Points
    70
    Par défaut Créer une contrainte d'unicité évoluée
    Bonjour,

    Je cherche le moyen de créer une contrainte d'unité mais pas directe.
    Je m'explique, j'ai 4 tables:
    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
     
    CREATE TABLE famille_produit (t1_id NUMBER(18,0) NOT NULL, t1_label VARCHAR(50));
    ALTER TABLE famille_produit ADD CONSTRAINT pk_t1 PRIMARY KEY t1_id;
     
    CREATE TABLE produit (t2_id NUMBER(18,0) NOT NULL, t2_label VARCHAR(50), t1_id NUMBER(18,0) NOT NULL);
    ALTER TABLE produit ADD CONSTRAINT pk_t2 PRIMARY KEY t2_id;
    ALTER TABLE produit ADD CONSTRAINT fk_t2 FOREIGN KEY (t1_id) REFERENCES T1 (t1_id);
     
    CREATE TABLE T3 (t3_id NUMBER(18,0) NOT NULL, t3_label VARCHAR(50));
    ALTER TABLE T3 ADD CONSTRAINT pk_t3 PRIMARY KEY t3_id;
     
    CREATE TABLE T4 (t2_id NUMBER(18,0) NOT NULL, t3_id NUMBER(18,0) NOT NULL);
    ALTER TABLE T4 ADD CONSTRAINT pk_t4 PRIMARY KEY (t2_id, t3_id);
    ALTER TABLE T4 ADD CONSTRAINT fk_t4_1 FOREIGN KEY (t2_id) REFERENCES produit (t2_id);
    ALTER TABLE T4 ADD CONSTRAINT fk_t4_2 FOREIGN KEY (t3_id) REFERENCES T3 (t3_id);
    Dans la table T4, je veux que pour un identifiant T3_ID:
    . avoir un seul enregistrement produit pour une famille produit.
    . autoriser plusieurs enregistrements produit, s'ils ne sont pas de la même famille.

    Je pensais utiliser un trigger, mais d'après ce que j'ai lu, ce n'est pas préconisé. Je ne vois pas comment faire autrement.
    Merci de votre aide.

  2. #2
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 114
    Points : 70
    Points
    70
    Par défaut
    Pour résoudre mon problème, j'ai utilisé une vue matérialisée avec une contrainte check sur une colonne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CREATE MATERIALIZED VIEW MV_CHECK_UNICITE
    REFRESH ON COMMIT AS
      SELECT COUNT(T4.*) AS count_value, T4.T3_id, produit.T1_id
      FROM T4
      INNER JOIN produit ON T4.T2_id = produit.T2_id
      GROUP BY T4.T3_id, produit.T1_id; 
     
    ALTER MATERIALIZED VIEW  MV_CHECK_UNICITE ADD CONSTRAINT CHK_UNICITE CHECK (count_value <= 1)

  3. #3
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Qu'est ce que la table T3 ?
    Votre contrainte ne devrait-elle pas être portée sur la table produit qui contient un lien vers la famille du produit ?
    Est-il pertinent que la famille ne soit pas renseignée dans la table T4 ?


    Pour le faire en trigger à partir de la 11G, vous pouvez utiliser un COMPOUND Trigger.
    Sinon c'est également possible via une vue matérialisée.
    Ou alors vous écrivez une procédure qui s'occupe de faire la transcation correctement (avec select for update pour vérification)

    Je vous recommande de lire :
    Best way to enforce cross-row constraints?

    Et aussi quelques infos sur la lecture consistante, au cas où :
    https://asktom.oracle.com/pls/apex/f...27330770500351

    [edit] : too late...

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 114
    Points : 70
    Points
    70
    Par défaut
    Pour donner plus de consistance à l'exemple:
    . la table T3 contient des commandes.
    . la table T4 permet de lier une commande à des produits.
    . Une commande est composée de plusieurs produits.
    . Pour une commande, chaque produit doit appartenir à une famille distincte.

    Au vu de cette spécification, je ne vois pas comment la contrainte peut porter sur la table produit.
    La famille n'est pas reportée dans la table T4 pour éviter toute redondance d'information. Et même si elle y était, on on pourrait pas utiliser cette information car la table est en mutation.

Discussions similaires

  1. [AC-2003] Créer une contrainte d'unicité basé sur deux champs(hors clé primaire)
    Par adelcrb dans le forum Modélisation
    Réponses: 1
    Dernier message: 31/08/2013, 21h06
  2. Réponses: 5
    Dernier message: 17/07/2008, 11h40
  3. Réponses: 4
    Dernier message: 15/02/2008, 15h24
  4. Réponses: 3
    Dernier message: 27/02/2007, 15h11
  5. Créer une contraintes pour une suppression
    Par subzero82 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 04/10/2005, 17h36

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