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

Requêtes MySQL Discussion :

Insert sur tables avec héritage [MySQL-5.5]


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    En formation
    Inscrit en
    Février 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : En formation

    Informations forums :
    Inscription : Février 2019
    Messages : 3
    Par défaut Insert sur tables avec héritage
    Bonjour tout le monde,

    Je ne trouve pas de réponse à mon problème, j'espère que vous pourrez m'aider.

    Voici le problème:

    j'ai 3 tables enfant qui héritent d'un parent (les pk des enfant sont aussi des fk qui pointent sur la pk du parent)

    - je ne veux pas tout mettre dans une seule table.
    - je veux conserver la table parent, pour pouvoir la requetter.

    Il y à t'il un moyen de faire un INSERT à la fois sur le parent et l'enfant?
    j'ai essayer de créer une VIEW qui regroupe enfant et parent mais l'INSERT ne fonctionne pas.

    Je sais que sur postgreSQL il y à une fonction INHERIT, il y a t'il quelquechose de similaire sur MySQL?
    Merci pour votre aide.

  2. #2
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 883
    Par défaut
    Salut alexraiden.

    Citation Envoyé par alexraiden
    je ne veux pas tout mettre dans une seule table.
    Vous cherchez à répartir le contenu de votre ligne fictive dans plusieurs tables afin d'éviter le redondance d'information.
    Pour ce faire, il vous faux un critère pour effectuer le répartition entre toutes vos tables.

    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
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `pere`
    --------------
     
    --------------
    CREATE TABLE `pere`
    ( `id`    integer unsigned  NOT NULL auto_increment primary key,
      `mess`  varchar(255)      NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    DROP TABLE IF EXISTS `mere`
    --------------
     
    --------------
    CREATE TABLE `mere`
    ( `id`    integer unsigned  NOT NULL auto_increment primary key,
      `info`  varchar(255)      NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    DROP TABLE IF EXISTS `fille`
    --------------
     
    --------------
    CREATE TABLE `fille`
    ( `id`         integer unsigned  NOT NULL auto_increment primary key,
      `lib`        varchar(255)      NOT NULL,
      `clef_pere`  integer unsigned  NOT NULL,
      `clef_mere`  integer unsigned  NOT NULL,
      CONSTRAINT `FK_PERE` FOREIGN KEY (`clef_pere`) REFERENCES `pere` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
      CONSTRAINT `FK_MERE` FOREIGN KEY (`clef_mere`) REFERENCES `mere` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    DROP PROCEDURE IF EXISTS `remplir`
    --------------
     
    --------------
    CREATE PROCEDURE `remplir` (IN _mess  text,
                                IN _info  text,
                                IN _lib   text)
    BEGIN
      DECLARE _flag  integer          default null;
      DECLARE _pere  integer unsigned default null;
      DECLARE _mere  integer unsigned default null;
     
      set _flag = (select 1 from `pere` where mess = _mess);
     
      if (_flag = 1) then
           set _pere = (select id from `pere` where mess = _mess);
      else insert into `pere` (`mess`) values (_mess);
           set _pere = last_insert_id();
      end if;
     
      set _flag = (select 1 from `mere` where info = _info);
     
      if (_flag = 1) then
           set _mere = (select id from `mere` where info = _info);
      else insert into `mere` (`info`) values (_info);
           set _mere = last_insert_id();
      end if;
     
     
    insert into `fille` (`lib`,`clef_pere`,`clef_mere`) values (_lib,_pere,_mere);
    END
    --------------
     
    --------------
    commit
    --------------
     
    --------------
    call `remplir` ('papa 1', 'maman 1', 'enfant 1')
    --------------
     
    --------------
    call `remplir` ('papa 2', 'maman 2', 'enfant 2')
    --------------
     
    --------------
    call `remplir` ('papa 1', 'maman 2', 'enfant 3')
    --------------
     
    --------------
    call `remplir` ('papa 2', 'maman 1', 'enfant 4')
    --------------
     
    --------------
    call `remplir` ('papa 1', 'maman 1', 'enfant 5')
    --------------
     
    --------------
    select * from `pere`
    --------------
     
    +----+--------+
    | id | mess   |
    +----+--------+
    |  1 | papa 1 |
    |  2 | papa 2 |
    +----+--------+
    --------------
    select * from `mere`
    --------------
     
    +----+---------+
    | id | info    |
    +----+---------+
    |  1 | maman 1 |
    |  2 | maman 2 |
    +----+---------+
    --------------
    select * from `fille`
    --------------
     
    +----+----------+-----------+-----------+
    | id | lib      | clef_pere | clef_mere |
    +----+----------+-----------+-----------+
    |  1 | enfant 1 |         1 |         1 |
    |  2 | enfant 2 |         2 |         2 |
    |  3 | enfant 3 |         1 |         2 |
    |  4 | enfant 4 |         2 |         1 |
    |  5 | enfant 5 |         1 |         1 |
    +----+----------+-----------+-----------+
    --------------
    select     t2.mess as père,
               t3.info as mère,
               t1.lib  as enfant
     
         from  `fille` as t1
     
    inner join  `pere` as t2
            on  t2.id = t1.clef_pere
     
    inner join  `mere` as t3
            on  t3.id = t1.clef_mere
    --------------
     
    +--------+---------+----------+
    | père   | mère    | enfant   |
    +--------+---------+----------+
    | papa 1 | maman 1 | enfant 1 |
    | papa 1 | maman 1 | enfant 5 |
    | papa 2 | maman 1 | enfant 4 |
    | papa 1 | maman 2 | enfant 3 |
    | papa 2 | maman 2 | enfant 2 |
    +--------+---------+----------+
    --------------
    COMMIT
    --------------
     
    Appuyez sur une touche pour continuer...
    @+

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 602
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 602
    Billets dans le blog
    10
    Par défaut
    Bonjour

    Autre solution : créer un trigger before insert qui crée le ou les parent(s) avant l'insertion dans la table enfant

  4. #4
    Candidat au Club
    Homme Profil pro
    En formation
    Inscrit en
    Février 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : En formation

    Informations forums :
    Inscription : Février 2019
    Messages : 3
    Par défaut
    @Artemus24: Merci pour votre exemple très complet, je vais pouvoir l'adapter à mon cas .

    @escartefigue: En effet, je dois créer le parent avant l'enfant. j'ai réfléchi à un trigger before insert sur l'enfant mais je ne vois pas comment un trigger sur l'enfant peut créer une row sur la table parent? (a ma conaissance on ne peut pas fournir de paramètres à un trigger)

    En tout cas merci pour vos réponses !

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 602
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 602
    Billets dans le blog
    10
    Par défaut
    En effet, l'usage d'un trigger before insert n'est possible que pour les cas où la table parente ne pilote que l'identifiant, c'est à dire dans le cas d'un héritage dont le surtype (le parent donc) ne possède pas d'attribut en dehors de l'identifiant

  6. #6
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 883
    Par défaut
    Salut à tous.

    Citation Envoyé par Escartefigue
    Autre solution : créer un trigger before insert qui crée le ou les parent(s) avant l'insertion dans la table enfant
    A moins d'avoir compris autre chose que vous, il s'agit d'effectuer le remplissage de plusieurs tables à partir d'une seule ligne à insérer.
    D'où le fait que j'utilise dans mon exemple une procédure stockée qui va répartir les données dans plusieurs tables à partir d'une ligne fictive à insérer.

    Citation Envoyé par alexraiden
    j'ai réfléchi à un trigger before insert sur l'enfant mais je ne vois pas comment un trigger sur l'enfant peut créer une row sur la table parent?
    Autre problème que vous signalez à juste titre, on ne peut pas remplir une table parent à partir d'une table enfant à cause que le déclencheur de la table enfant ignore les colonnes de la table parent.
    Ou alors, comme le suppose Escartefigue, (ce que j'ai compris), vous devez faire plusieurs passages afin d'extraire à chaque fois les lignes pour la première table parent, extraire ensuite les lignes pour la deuxième table parent et ainsi de suite, puis finir avec les lignes de la table enfant, afin de respecter la logique des insertions sur les clefs étrangères.

    C'est pourquoi, l'usage de la procédure stockée permet de simuler l'insertion d'une ligne fictive !
    Et cela permet de ne faire qu'un seul passage et non un passage par table à mettre à jour.

    Par contre, vous n'avez pas expliqué, alexraiden, comment vos données se présentent ?
    S'agit-il de données venant d'excel ? Dans ce cas il existe une autre solution.

    @+

  7. #7
    Candidat au Club
    Homme Profil pro
    En formation
    Inscrit en
    Février 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : En formation

    Informations forums :
    Inscription : Février 2019
    Messages : 3
    Par défaut
    non les données ne viennent pas d'excel, petite appli qui récupérè les données saisie par l'utilisateur et node.js en backoffice,
    j'ai mis toutes mes requêtes dans des procédures,
    voila

  8. #8
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 883
    Par défaut
    Salut alexraiden.

    Très bien !

    Bonne continuation.

    Cordialement.
    Artemus24.
    @+

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

Discussions similaires

  1. [2008R2] Problème d'insertion sur table avec une unique colonne identity
    Par Kropernic dans le forum Développement
    Réponses: 12
    Dernier message: 04/10/2013, 08h16
  2. Réponses: 1
    Dernier message: 10/04/2008, 11h44
  3. Insert avec select sur table avec Trigger d'insertion
    Par bran_noz dans le forum Développement
    Réponses: 5
    Dernier message: 23/12/2005, 14h38
  4. Requete sur table avec Tableau
    Par Sichagadel dans le forum Langage SQL
    Réponses: 3
    Dernier message: 08/11/2005, 14h05
  5. [debutant] select-insert sur tables de bases differentes
    Par RedMax dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/10/2004, 18h59

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