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

PostgreSQL Discussion :

Héritage Insertion d'un enfant avec reprise champ parent


Sujet :

PostgreSQL

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 25
    Points : 13
    Points
    13
    Par défaut Héritage Insertion d'un enfant avec reprise champ parent
    Bonjour,
    je recherche actuellement une solution qui me permette lors d'une insertion d'un nouvel enregistrement d'une table enfant de récupérer les valeurs héritées d'un enregistrement parent en spécifiant l'identifiant du parent.

    J'ai vu dans la citation de la documentation Postgresql suivante que c'était possible mais cela n'est pas bien clair (voir Chapitre 35, Système de règles) pour les insertions :
    "On peut espérer que les données soient magiquement routées vers la table capitales mais cela n'arrive pas : INSERT insère toujours dans la table indiquée. Dans certains cas, il est possible de rediriger l'insertion en utilisant une règle (voir Chapitre 35, Système de règles)."

    Ma base de données postgresql version 8.4.11.
    J'ai donc une table contractProject qui est parente d'une table contractContract .
    Je souhaiterais qu'à chaque insertion dans la table contractContract je puisse éviter de recupérer les valeurs des champs de son parent avec son identifiant depuis l'applicatif.

    S'il y existe un exemple?
    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Je trouve le système d'héritage de postgres assez bancal en fait.

    par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    create table t_parent (id integer primary key, nom varchar(32));
    create table t_enfant (val_enfant varchar(32)) inherits (t_parent);
     
     
    insert into t_enfant values (1, 'parent1', 'enfant1');
    insert into t_parent values (1, 'parent2');
     
     
    select * from t_parent
    -------------------
    1;"parent2"
    1;"parent1"
    Bref il faut mettre en place d'autre règle afin de ne pas avoir ce genre de cas possible...
    cad Une PK sur la table enfant + une règle check pour vérifier que l'id de l'enfant n'existe pas dans la table parent ...


    Du coup, autant créer soit même l'héritage avec une relation de type 1/1.

    Création des tables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    create table t_parent(id integer primary key, nom varchar(32));
    create table t_enfant (id integer primary key references t_parent(id) , val_enfant varchar(32));
    Création de la vue pour la table enfant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    create view v_enfant as (
    select a.id, a.nom, b.val_enfant
    from t_parent a
    inner join t_enfant b on a.id = b.id);
    Ensuite on crée des fonctions qui permettront d'updater / inserer / delete dans la vue en question via des trigger sur cette vue.

    Un exemple d'insertion :
    Trigger insert :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    CREATE OR REPLACE FUNCTION "_INSERT_V_ENFANT"()
      RETURNS trigger AS
    $BODY$
    declare £id integer;
    begin
    insert into t_parent (nom) values (new.nom) returning id into £id;
    insert into t_enfant (id, val_enfant) values (£id, new.val_enfant);
    return new;
    end $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    On bind le trigger sur la vue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CREATE TRIGGER "_Insert"
      INSTEAD OF INSERT
      ON v_enfant
      FOR EACH ROW
      EXECUTE PROCEDURE "_INSERT_V_ENFANT"();

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    Bonjour,
    Tout d'abord merci de cette réponse rapide, mais en fait j'ai dû mal m'expliquer.
    J'ai actuellement une modélisation postgresql 8.4.11 qui me convient avec les héritages car j'ai des références avec d'autres tables et cela fonctionne très bien.
    Mais j'aimerais pouvoir récupérer les valeurs des champs du parent si je créer un enfant avec le même identifiant du parent. En bref transformer un project en contract.
    Exemple :
    j'ai une table contractProjet avec nom et idProject:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TABLE "contractProjects"
    (
      "idProject" serial NOT NULL, -- identifiant du contract ou du projet 
      "nom" character varying(255), -- Nom du projet 
      CONSTRAINT "contractProjects_pkey" PRIMARY KEY ("idProject" )	
    )
    WITH (
      OIDS=FALSE
    );
    Puis j'ai une table enfant avec des champs supplémentaires pour le contrat réel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE TABLE "contractContracts"
    (  
      "champ1" character varying(255), -- Champ en saisie libre 1
      "champ2" character varying(255), -- Champ en saisie libre 2
      "champ3" character varying(255), -- Champ en saisie libre 3        
      CONSTRAINT "contractContracts_pkey" PRIMARY KEY ("idProject" )
    )INHERITS ("contractProjects")
    WITH (
      OIDS=FALSE
    );
    Ce que je souhaite c'est avoir une solution (règle, trigger ou autre) qui me permette de récupérer le nom du projet si je mets l'id du parent (contractProject) lors de l'INSERT du contrat.
    Je veux éviter de passer par du dev dans l'applicatif !
    Le problème d'avoir les id identiques pour un projet et un contrat réel ne me pose pas trop de problème si j'utilise la clause ONLY.
    Si je passe par une relation 1-1 il faut que je modifie la conception et les références. Plus les modifications des champs dans le parent etc..
    Ce que je ne veux pas faire car tout fonctionne bien, mais si je suis obligé alors je vais essayer
    Merci d'avance.

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,


    Ca ne marche pas comme ça l'héritage au sens postgresql.


    Les données ne sont pas propagées dans la table mère.
    Du coup toutes vos données sont dans votre table fille.

    C'est pour ca que je trouve ça bancal.

  5. #5
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    Actuellement et effectivement les données ne sont pas stockés dans la table mère mais apparaissent si je crée un enregistrement fils.
    Mais existe-t-il alors une solution par trigger ou règle pour que je puisse récupérer les valeurs d'un enregistrement parent lorsque je crée un fils avec le même id?
    Merci d'avance !

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Je trouve ca pourri comme approche mais bon (duplication de donnée, incohérence etc)


    Regardez du côté des fonctions. (qui peuvent retourner une ligne / table).

    Et faites vos insert avec ces fonctions.

  7. #7
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    Ok, donc d'après ce que vous me dites Postgre a mis la possibilité de faire de l'héritable mais c'est très limité donc pourri!
    Pourquoi ils l'ont mis pour rien?
    Alors d'après vous, il faut mieux passer par des relations 1-1, ca veut dire qu'il faut jamais utiliser les héritages dans postgre.
    Ok je vais revoir la conception alors, d'autant plus qu'il faut que je garde à l'esprit que la base sera amenée à migrer sous oracle.
    Je suis donc vos conseils car je n'ai pas trop d'experience en postgre.
    Merci je vais revoir ma copie

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    L'héritage postgresql est un héritage de structure de données, pas de contenu.

    Pour diverses raisons dont peut-être la lecture de la doc en diagonale, les développeurs partent parfois bille en tête sur des idées fausses concernant cette fonctionnalité.

    Voir par exemple cette autre discussion:
    http://www.developpez.net/forums/d10...ge-postgresql/

    ou celle-là:
    http://www.developpez.net/forums/d95...ritage-tables/

    où quelques-unes de ces idées fausses sont traitées.

  9. #9
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    Merci bien à tous pour les réponses mais je vais m'orienter vers la solution proposé par punkoff car la base est amenée à migrer vers oracle.
    Ce qui me pousse à penser que les particularités de l'héritage postgresql vont se transformer en boulet lors de la migration.

Discussions similaires

  1. Requête SQL .. lignes enfants avec valeurs du parent
    Par mienmien69100 dans le forum Langage SQL
    Réponses: 13
    Dernier message: 21/05/2014, 17h25
  2. Réponses: 2
    Dernier message: 20/07/2011, 01h15
  3. [MySQL] erreur à l'insert d'une entrée avec un champ ENUM
    Par mounia.n dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 27/05/2008, 16h44
  4. Problème d'insertion avec un champ Date/Heure ?
    Par bds2006 dans le forum Bases de données
    Réponses: 1
    Dernier message: 26/06/2006, 10h37
  5. Réponses: 3
    Dernier message: 19/11/2004, 21h48

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