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

Schéma Discussion :

Problème de relations


Sujet :

Schéma

  1. #81
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 912
    Points
    38 912
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    είσαι άλλος ένας !
    Je n'ai pas changé comme dirait Julio, mais je prépare un séjour ibérique, alors je m'entraine... C'est pas gagné, je pars de zéro et il ne me reste que quelques semaine.
    Bon je sais déjà commander un demi, c'est l'essentiel pour survivre


    Citation Envoyé par fsmrel Voir le message
    Je pense que le Capitaine en conviendra, même s’il est aussi rouillé que moi dans la mise en oeuvre d’Access...
    Quant à la rouille, elle aurait un charme fou si elle ne s'attaquait qu'aux grilles, c'est une Maxime , mais me concernant, elle gagne d'autres terrains

  2. #82
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 906
    Points
    30 906
    Billets dans le blog
    16
    Par défaut Noeuds dans le cerveau, jointure avec Access ;)
    Oyez !

    Un détour du côté de µSoft SQL Server et de µSoft Access.

    Reprenons le MCD proposé précédemment. L’entité-type Frenesie disparaît car un monstre a au moins et au plus une frénésie et, en contrepartie, l’entité-type Monstre est dotée d’un attribut ad-hoc, nommé Trophee en remplacement de Frenesie.

    Le MCD devient celui-ci :

    Les CREATE TABLE proposés à SQL Server :

    Code SQL : 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
    CREATE TABLE Utilisateur
    (
        UtilisateurId SMALLINT NOT NULL
    ,   UtilisateurNom VARCHAR(24) NOT NULL
    ,   CONSTRAINT Utilisateur_PK PRIMARY KEY(UtilisateurId)
    );
    CREATE TABLE Groupe
    (
        GroupeId SMALLINT NOT NULL
    ,   GroupeNom VARCHAR(24) NOT NULL
    ,   CONSTRAINT Groupe_PK PRIMARY KEY(GroupeId)
    ,   CONSTRAINT GroupeMaxId CHECK(GroupeId BETWEEN 0 AND 7)
    );
    CREATE TABLE Formation
    (
        FormationId SMALLINT NOT NULL
    ,   FormationNom VARCHAR(24) NOT NULL
    ,   GroupeId  SMALLINT NOT NULL
    ,   CONSTRAINT Formation_PK PRIMARY KEY(FormationId)
    ,   CONSTRAINT Formation_AK UNIQUE(FormationNom)
    ,   CONSTRAINT Formation_Groupe_FK FOREIGN KEY(GroupeId) REFERENCES Groupe(GroupeId)
    );
     
    CREATE TABLE Rencontrer
    (
        UtilisateurId SMALLINT NOT NULL
    ,   FormationId SMALLINT NOT NULL
    ,   CONSTRAINT Rencontrer_PK PRIMARY KEY(UtilisateurId, FormationId)
    ,   CONSTRAINT Rencontrer_Utilisateur_FK FOREIGN KEY(UtilisateurId) REFERENCES Utilisateur(UtilisateurId)
    ,   CONSTRAINT Rencontrer_Formation_FK FOREIGN KEY(FormationId) REFERENCES Formation(FormationId)
    );
     
    CREATE TABLE Monstre
    (
        MonstreId SMALLINT NOT NULL
    ,   MonstreNom VARCHAR(24) NOT NULL
    ,   Trophee VARCHAR(24) NOT NULL
    ,   CONSTRAINT Monstre_PK PRIMARY KEY(MonstreId)
    ,   CONSTRAINT Monstre_AK UNIQUE(MonstreNom)
    );
     
    CREATE TABLE Composer
    (
        FormationId SMALLINT  NOT NULL
    ,   MonstreId SMALLINT  NOT NULL
    ,   CONSTRAINT Composer_PK PRIMARY KEY(FormationId, MonstreId)
    ,   CONSTRAINT Composer_Formation_FK FOREIGN KEY(FormationId) REFERENCES Formation(FormationId)
    ,   CONSTRAINT Composer_Monstre_FK FOREIGN KEY(MonstreId) REFERENCES Monstre(MonstreId)
    );
     
    CREATE TABLE Acquerir
    (
        UtilisateurId SMALLINT  NOT NULL
    ,   MonstreId SMALLINT  NOT NULL
    ,   FormationId SMALLINT  NOT NULL 
    ,   CONSTRAINT Acquerir_PK PRIMARY KEY(UtilisateurId, MonstreId)
    ,   CONSTRAINT Acquerir_Composer_FK FOREIGN KEY(FormationId, MonstreId) REFERENCES Composer(FormationId, MonstreId)
    ,   CONSTRAINT Acquerir_Rencontrer_FK FOREIGN KEY(UtilisateurId, FormationId) REFERENCES Rencontrer(UtilisateurId, FormationId)
    );

    Quelques inserts :

    Code SQL : 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
    insert into Groupe (GroupeId, GroupeNom) values
      (0,'g0')
    , (1,'g1')
    , (2,'g2')
    , (3,'g3')
    , (4,'g4')
    , (5,'g5')
    , (6,'g6')
    , (7,'g7')
    ;
    select '' as Groupe,* from Groupe ;
     
    insert into Formation (FormationId,FormationNom, GroupeId) values
      (1,'f1', 1)
    , (2,'f2', 1)
    , (3,'f3', 3)
    , (5,'f5', 3)
    ;
    select '' as Formation, * from Formation ;
     
    insert into Monstre values
      (1,'m1', 'ananas')
    , (2,'m2', 'bonbons')
    , (3,'m3', 'chocolat')
    , (4,'m4', 'nougats')
    , (5,'m5', 'caramels')
    ;
    select '' as Monstre,* from Monstre ;
     
    insert into Composer values
      (1,1)  -- f1,m1
    , (1,2)  -- f1,m2
    , (1,3)  -- f1,m3
    , (1,5)  -- f1,m5 chouffe !
    , (2,1)  -- f2,m1
    , (2,3)  -- f2,m3
    , (2,4)  -- f2,m4
    , (2,5)  -- f2,m5
    , (3,2)  -- f3,m2
    , (3,5)  -- f3,m5
    ;
    select '' as Composer,* from Composer ;
     
    insert into Utilisateur values
      (1,'u1')
    , (2,'u2')
    , (3,'u3')
    ;
    select '' as Utilisateur, * from Utilisateur ;
     
    insert into Rencontrer values
      (1,1) -- u1,f1 
    , (1,2) -- u1,f2
    , (2,1) -- u2,f1
    , (2,2) -- u2,f2
    , (2,3) -- u2,f3
    , (2,5) -- u2,f5
    ;
    select '' as Rencontrer, * from Rencontrer ;
     
    insert into Acquerir values
      (1,1,1)  -- u1,m1,f1 -- ok
    , (1,3,1)  -- u1,m3,f1 -- ok
    --, (1,3,2)  -- u1,m3,f2 -- pk en double {u1,m3}, 
    , (1,4,2)  -- u1,m4,f2 -- ok
    --, (1,1,2)  -- u1,m1,f2 -- clé en double !
    --, (1,4,1)  -- u1,m4,f1 -- clé en double !
    ,  (2,1,1)  -- u2,m1,f1 -- ok
    --,  (2,3,3)  -- u2,m3,f3 -- m3 n'appartient pas à f3
    ;
    select '' as Acquerir, * from Acquerir ;
     
    Voici une requête (toujours avec SQL Server) permettant de savoir quels trophées ont été acquis par quels utilisateurs :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select distinct u.UtilisateurNom, f.FormationNom, m.Trophee
    from Utilisateur as u join Rencontrer as r on u.UtilisateurId = r.UtilisateurId
                          join Acquerir as q on q.UtilisateurId = r.UtilisateurId 
                                            and q.FormationId = r.FormationId 
                          join Monstre as m on m.MonstreId = q.MonstreId
                          join Formation as f on f.FormationId = r.FormationId ;
     
    N’importe quel SGBD digne ce nom exécute cette requête sans problème. Là où ça devient croquignolesque, c’est quand on la soumet à Access.

    On a droit à ce message d’erreur :

    « Erreur de syntaxe dans la clause FROM. »

    Le mot « join » y est mis en cause. Je consulte Microsoft Learn qui me dit :

    « Notez que les noms des tables sont séparés par les mots clés INNER JOIN »

    J’en prends acte, bien que le mot « INNER » soit superflu et n’existe même pas (heureusement) dans le Modèle Relationnel de Données. Après avoir consciencieusement ajouté ce mot inutile, je resoumets la requête en attente du prochain gag...

    Au résultat :
     
    « Erreur de syntaxe (opérateur absent) dans l’expression
    "u.UtilisateuId =r.UtilisateuId inner join Acquerir as q on q.UtilisateuId = r.UtilisateuId" »
     
    Je me demande ce que peut bien être cet opérateur. Je consulte à nouveau Microsoft Learn pour connaître la liste des opérateurs connus d’Access, mais je n’en tire rien, d’autant que l’expression en cause est relationnellement parfaitement légale.

    Je poursuis la présentation de JOIN dans Microsoft Learn et tombe sur ceci :

    « Notez que la première clause JOIN est entre parenthèses pour être séparée logiquement de la seconde clause JOIN. »
     
    L’instruit, le foutriquet qui a concocté cela aurait dû suivre des cours de logique et lire les bons auteurs (Quine par exemple) !

    On perd en simplicité, mais on gagne en complexité. Je dois virer les tokens (u., r., etc.) ci-dessous :

    Utilisateur as u inner join Rencontrer as r on u.UtilisateurId = r.UtilisateurId

    et dois les remplacer par :

    Utilisateur inner join Rencontrer on Utilisateur.UtilisateurId = Rencontrer.UtilisateurId

    Etc. Jusque-là, rien de bien méchant, mais après avoir effectué quelques tentatives infructueuses d’utilisation des parenthèses, j’ai fini par fouiller chez DVP et suis tombé sur une interrogation  de jjcasalo confronté au même problème, ce à quoi marot_r apporte la réponse suivante :
     
    Citation Envoyé par marot_r
    Le SQL de Access a ses propres particularités, donc je te suggère de refaire ta requête avec l'éditeur de requête, ça se fait en faisant des glissé/déplacé plutôt que d'essayer d'adapter du SQL venant d'une autre BD.
    Message reçu. Je vote pour marot_r et crée donc ex nihilo une requête dans laquelle je « glisse » les tables en cause, et voilà le résultat graphique auquel Codd et Date n’auraient certainement pas pensé :
     


     
    Et si je regarde le contenu de la requête en mode SQL fournie par Access (après avoir complété la 1re ligne avec les noms des attributs à afficher au résultat) :
     
     
    Waouh ! Ben mon vieux ! C'est digne d’Hilarion !

    A titre de curiosité, je complète la requête graphique, en y ajoutant la table Composer (bien qu’inutile pour le besoin, à moins que le Capitaine, Achille, SQLpro, CinePhil et autres baroudeurs ne me démentent) :
     
     
    La requête mijotée par Access devient celle-ci, du Hilarion++ :
     
     

    Qui dit mieux ? Achille parlait de nœuds dans le cerveau...

    Que dire ici ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #83
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 912
    Points
    38 912
    Billets dans le blog
    9
    Par défaut
    Bonjour François

    Cette syntaxe pour les jointures n'est pas propre à ACCESS, elle est même obligatoire dans le cas ou l'on combine des jointures internes et externes, et ce quel que soit le SGBD.
    J'ai d'ailleurs écrit un article de blog sur ce sujet, voir ICI

    Ce qui est surprenant, c'est que ACCESS applique cette syntaxe alors qu'il n'y a que des jointures internes, ça n'a pas d'intérêt dans ce cas précis, la jointure interne étant commutative et transitive
    De plus, les parenthèses n'ont aucun intérêt ici, l'optimiseur du SGBD n'en tient pas compte, il choisit sa stratégie de jointure indépendamment de celles-ci (ou alors c'est une spécificité de ACCESS).

  4. #84
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 906
    Points
    30 906
    Billets dans le blog
    16
    Par défaut
    Merci Capitaine,

    Citation Envoyé par escartefigue
    Cette syntaxe pour les jointures n'est pas propre à ACCESS, elle est même obligatoire dans le cas ou l'on combine des jointures internes et externes, et ce quel que soit le SGBD.
    J’entends bien, mais qu’Access fasse comme SQL Server et les autres, et qu’il nous foute la paix avec son obligation adjudantesque et non justifiée de parenthèses quand on ne code que des jointures internes.

    En passant, le terme "jointure externe" est fallacieux, car un "outer join" n’a rien d’une jointure, c’est en réalité une union !

    Combiner jointure interne et "externe" (sic), c’est tout bonnement marier la carpe et le lapin, du fait de la présence de l’affreux bonhomme Null, avec toutes les conséquences funestes que cela entraîne (logique trivalente mal maîtrisée et j’en passe...)

    Tu sais que pour ma part je m’oblige à déclarer "NOT NULL" chaque colonne de table. Cela dit, Null s’invite dès qu’il le peut, mais je reste vigilant et me sers au besoin du bouclier COALESCE.

    Je crée par exemple les deux tables t1 et t2 suivantes, joignables sur leur clé primaire :

    Code SQL : 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 t1 
    (
       id1 smallint not null
     , produit varchar (16) not null
     , ttc int not null
    , constraint t1_PK primary key (id1)
    ) ;
     
    create table t2 
    (
       id2 smallint not null
     , origine varchar (16) not null
     , qualite varchar(16) not null
    , constraint t2_PK primary key (id2)
    ) ;
    Ces tables parlent d’elles-mêmes.

    Quelques valeurs :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    insert into t1 values
      (1, 'nougats', 100)
    , (3, 'caramels', 150)
    , (2, 'bonbons', 120)
    ;
    insert into t2 values
      (1, 'Montélimar', 'supérieure')
    , (3, 'Isigny', 'très bons')
    , (5, 'Chine', 'moyen')
    ;

    Si je procède non pas à leur jointure, mais à leur union :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select t1.id1, t1.produit, t1.ttc, t2.origine, t2.qualite
    from t1 join t2 on t1.id1 = t2.id2
     
    union
     
    select t1.id1, t1.produit, t1.ttc, 'on sait pas', 'indéfinie'
    from t1
    where t1.id1 not in (select t1.id1 
                         from t1, t2 
                         where t1.id1 = t2.id2)
    alors je produis le résultat valide suivant (logique bivalente oblige) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    id1	produit		ttc	origine		qualite
    1	nougats		100	Montélimar	supérieure
    2	bonbons		120	on sait pas	indéfinie
    3	caramels	150	Isigny		très bons
    Si j’avais la nostalgie de l’outer join, j’utiliserais le bouclier coalesce :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select t1.id1, t1.produit, t1.ttc
    , coalesce(t2.origine, 'on sait pas') as origine
    , coalesce(t2.qualite, 'indéfinie') as qualite
    from t1 left outer join t2 on t1.id1 = t2.id2
    et je produirais le même résultat, dans lequel Null est donc exclu.

    Ma position vis-à-vis de l’outer join est du genre de celle de Jean Yanne à propos des routes départementales...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  5. #85
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 912
    Points
    38 912
    Billets dans le blog
    9
    Par défaut
    @deedolith : toutes mes excuses pour cette digression bien en marge du sujet

    @François : pour des raisons pragmatiques, je préfère de loin utiliser une jointure externe plutôt qu'une union basée sur une sous-requête corrélée, ce sera plus performant et bien entendu conforme à la norme SQL2 (SQL 1992) qui a ajouté les jointures externes. Ceci n'empêche en rien, au contraire, d'utiliser la fonction COALESCE ou la fonction NULLIF() pour se débarrasser des marqueurs NULL comme dans ton dernier exemple et se simplifier ainsi la tâche

    À l'extrême rigueur, une union basée sur un test d'existence NOT EXISTS plutôt qu'un NOT IN sera un peu plus performant, mais dans les deux cas, sur le plan de la compréhension et donc de la maintenance, voilà de quoi en dérouter plus d'un

  6. #86
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 906
    Points
    30 906
    Billets dans le blog
    16
    Par défaut Triggers et data macros
    Bonsoir,

    Citation Envoyé par Capitaine
    @François : pour des raisons pragmatiques, je préfère de loin utiliser une jointure externe plutôt qu'une union basée sur une sous-requête corrélée, ce sera plus performant et bien entendu conforme à la norme SQL2 (SQL 1992) qui a ajouté les jointures externes.
    Je suis évidemment d’accord quant au pragmatisme, mais il faut quand même que les plus jeunes se remémorent la différence qu’il y a entre une union (opération apprise à l’école) et une jointure...
    Pour mémoire, le terme « jointure » est l’apocope de « jointure naturelle ». La jointure naturelle est elle-même un cas particulier de l'équi-jointure, débarrassée des attributs redondants superflus (l’équi-jointure est une composition de relations au sens mathématique). Plus généralement, une équi-jointure est une restriction d’un produit cartésien, selon une condition de rapprochement. Voir par exemple ce qu’écrit le professeur Georges Gardarin dans Bases de données.

     
    @deedolith

    Nos débats avec le Capitaine ne concernent pas forcément votre sujet…
    Je me suis quand même penché sur la contrainte :
     
    Citation Envoyé par deedolith
    Une formation comprend 1 à 6 monstres.
     
    Avec un SGBD comme DB2, SQL Server, etc., je ne sais pas ce qu’en pensent le Capitaine et Achille, mais il me paraît approprié de mettre en oeuvre un trigger.

    Exemple où l’on prend en compte les inserts de masse (SQL Server) :

    Code SQL : 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
    create trigger ComposerKount on Composer after insert as
    begin 
      declare @n int -- comptage des formations par monstre
      declare @max tinyint = 6 -- max autorisé par monstre
      declare @errId as int = 314115 – numéro d’erreur
      declare @errTexte as varchar (255) -- message d'erreur
     
      select @n = count(FormationId) from Composer
      group by MonstreId having count(MonstreId) > @max
     
      if @n > 0
        begin
          set @errTexte = 'Le nb de formations par monstre doit être < ' 
                        + cast(@max+1 as varchar) + '.'
          ; throw @errId, @errTexte, 16
      end
    end

    On peut varier à l’infini, par exemple :

    Code SQL : 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
    create trigger ComposerKount on Composer after insert as
    begin 
      declare @n int -- comptage des formations par monstre (table Composer)
      declare @nInserted int -- comptage des formations par monstre (Inserted)
      declare @max tinyint = 6 -- max formations par monstre
      declare @errId as int = 314115  -- numéro de l'erreur à afficher
      declare @errTexte as varchar (255) -- message d'erreur
      declare @paire as varchar(32) ; -- paire FormationId, MonstreId
     
      declare @tableTout table (paire varchar(64) not null) ; -- image de la table Composer
      declare @tableInserted table (paire varchar(64) not null) ;  -- idem, mais inserted seuls
     
      insert into @tableTout (paire) 
        select cast(FormationId as varchar(8))  + ', ' + cast(MonstreId as varchar(8))  
        from Composer 
        where Monstreid in 
          (select MonstreId
           from Composer
           group by MonstreId
           having count(Monstreid) > @max) ;
     
      set @n = (select count(*) from @tableTout) ;      
     
      insert into @tableInserted (paire) 
        select cast(FormationId as varchar(8))  + ', ' + cast(MonstreId as varchar(8))  
        from Inserted 
        where Monstreid in 
          (select MonstreId
           from Composer  
           group by MonstreId
           having count(Monstreid) > @max) ;
     
      set @nInserted = (select count(*) from @tableInserted) ;      
     
      if @n > 0
        begin
          if @nInserted > 1
            begin
              set @errTexte = 
                    char(13)
                 + 'Le nombre de formations par monstre doit être < ' 
                 + cast(@max+1 as varchar) + '.'
                 + char(13)
                 + 'Ainsi, avec la paire {formation, monstre} : {'
                 + (select max(paire) from @tableTout) + '}'
                 + ', il y a une tentative d''ajout d''une ' 
                 + cast(@n as varchar(8))  
                 + 'ème formation pour le monstre... '
                 + char(13)
            end
          else         
            if @nInserted = 1
              begin
                set @errTexte = 
                    char(13)
                  + 'Le nombre de formations par monstre doit être < ' 
                  + cast(@max+1 as varchar) + '.'
                  + char(13)
                  + 'Ainsi, avec la paire {formation, monstre} : {'
                  + (select max(paire) from @tableInserted) + '}'
                  + ', il y a une tentative d''ajout d''une ' 
                  + cast(@n as varchar(8))  
                  + 'ème formation pour le monstre... '
                  + char(13)
              end
     
          ; throw @errId, @errTexte, 16
      end
    end

    Cela dit, par acquit de conscience, pour voir comment mettre en oeuvre avec Ms Access l’équivalent des triggers, j’ai regardé du côté des data macros, mais j’ai dû reculer...

    Deedolith, pensez-vous que les data macros soient jouables ? Et toi, vaillant Achille ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  7. #87
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 620
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 620
    Points : 56 862
    Points
    56 862
    Billets dans le blog
    40
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Deedolith, pensez-vous que les data macros soient jouables ? Et toi, vaillant Achille ?
    Même pas peur

  8. #88
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 118
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 118
    Points : 1 641
    Points
    1 641
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Deedolith, pensez-vous que les data macros soient jouables ? Et toi, vaillant Achille ?
    Sur Ms Access, les Macros de données (Data Macros ou Triggers en français) fonctionnent très bien. A mon sens, pour enforcer une relation 1,x (x étant une valeur finie) sont le meilleur choix.

    Par contre, leur mise en oeuvre est assez laborieuse.
    Faute à la méconnaissance du publique,
    un "langage" et un IDE pas très intuitif,
    la documentation minimaliste de Microsoft.

  9. #89
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 906
    Points
    30 906
    Billets dans le blog
    16
    Par défaut
    Bonsoir,

    @deedolith
     
    Comme vous dites, la mise en oeuvre des Data macros semble effectivement laborieuse...
     
     
    @Achille

    L’exemple que tu donnes ici est très éclairant . Encapsuler la complexité dans la requête R_frenesies_rencontres est quelque chose d’excellent.

    Je reprends ton approche. Supposons maintenant qu’un monstre ne puisse pas être associé à plus de 4 formations.
     
    Dans la table Composer on observe que le monstre m2 est déjà associé à 4 formations. Si on cherche à lui en ajouter une 5e, il faudra que le système empêche cela.
     
     


    A cet effet, je crée d’abord une requête SQL ad-hoc, comptant les formations pat monstre :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT MonstreId, Count(FormationId) AS FormationKount
    FROM Composer
    GROUP BY MonstreId
    HAVING count(MonstreId) > 4;
    Et lui donne un nom : ComposerKount.

    Je vais créer une data macro, qui aura pour nom ComposerKountTrigger. Je clique sur Table et me rends compte que pour contrôler les inserts, on a seulement droit à l’option « Après insertion », ce qui du reste me va bien.



     
    La data macro, que j’ai nommée ComposerKountTrigger, a pour objet d’exécuter la vue (requête) ComposerKount et d’y sélectionner les lignes pour lesquelles la colonne FormationKount prend une valeur > 0. S tel est le cas, alors on déclenche une erreur.




    Petit problème : j’ajoute une 5e formation pour le monstre 2, ce qui doit provoquer une erreur puisque ce monstre en a déjà 4.
    Eh bien, que nenni, pas d’erreur et l'insert est effectif...

     
     

    M'enfin...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  10. #90
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 620
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 620
    Points : 56 862
    Points
    56 862
    Billets dans le blog
    40
    Par défaut
    Hop,

    OK, je remets les mains dans la mélasse

    Pourquoi ne pas utiliser l'événement Avant Modification (insertion ou mise à jour) ? J'ai l'impression qu'avec Access, sur un événement Après..., c'est trop tard, la ligne est validée.

    Avec la requête ComposerKount :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT composer.MonstreId, Count(composer.FormationId) AS FormationKount
    FROM composer
    GROUP BY composer.MonstreId
    HAVING Count(composer.FormationId) >=4;

    Et la macro sur Avant Modification de la table composer :

    Nom : composerKount.png
Affichages : 111
Taille : 21,4 Ko

    Cela me semble plus clair en passant par une variable locale trouve qui passe à Vrai si pour la ligne insérée ou mise à jour, le monstre est déjà associé à 4 formations.
    J'obtiens bien le résultat voulu :

    Nom : composerKount2.png
Affichages : 111
Taille : 21,6 Ko

  11. #91
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 912
    Points
    38 912
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Je vous suis de loin, il y a trop longtemps que je n'ai plus pratiqué MS Access, mais c'est très intéressant et mériterait sans doute un article ou un billet de blog

  12. #92
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 906
    Points
    30 906
    Billets dans le blog
    16
    Par défaut
    Salve omnes,


    Citation Envoyé par Achille
    OK, je remets les mains dans la mélasse
    Quelle abnégation ! Un très grand merci à toi, Achille, et n’oublie pas de te laver les mains
     
    Citation Envoyé par Achille
    Pourquoi ne pas utiliser l'événement Avant Modification
    Quand j’ai vu les options ci-dessous, je me suis posé la question : pourquoi n’y a-t-il pas d’option « Avant insertion » ?

     

     
    Et j’ai automatiquement eu le réflexe « After insert », comme dans le cas du trigger que j’ai utilisé dans le contexte SQL Server (cf. ici). En passant, dans son excellent ouvrage SQL Server 2014, SQLpro rappelle qu’avec AFTER INSERT, les contrôles relatifs aux contraintes sont réalisés en premier. Mais, comme tu dis, Achille, manifestement µS Access a une approche radicalement différente et ignore superbement la mise en oeuvre de l’erreur que je lui propose.

    Ok, Achille, pour Access, « Avant modification » ne veut pas dire « before update », mais « avant mise à jour ou insertion » ! j’aurais dû avoir le réflexe de laisser traîner le pointeur de la souris sur ce « Avant modification » car alors Access m’aurait révélé un de ces secrets qu’il dissimule un peu partout, à la manière des jeux d’aventure (une frénésie en quelque sorte ) :



     
    Mais nom d’une pipe en bois, pourquoi ne pas disposer d’une grammaire digne ce nom ? Ras-le-bol d'aller à la pêche au pif...

    Par exemple, quand j’ai à mettre en oeuvre un trigger DB2, pas de problème, je trouve sur la toile la grammaire ad-hoc, en l’occurrence dans le document de référence « DB2 13 for z/OS SQL Reference », bien connu du Capitaine, (3000 pages quand même !)

    Lien : db2z13_sqlReferenceBook.pdf. Ainsi, page 1753, on a la synthèse de la grammaire pour les « triggers basiques »  :
     
     
     
    Et je vous fais grâce des triggers « advanced » !
     
     
    Citation Envoyé par escartefigue
    Je vous suis de loin, il y a trop longtemps que je n'ai plus pratiqué MS Access, mais c'est très intéressant et mériterait sans doute un article ou un billet de blog.
    Capitaine, je crois comprendre ta position vis-à-vis d’Access mais par esprit de sacrifice, te dévouerais-tu ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  13. #93
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 906
    Points
    30 906
    Billets dans le blog
    16
    Par défaut
    @Achille

    J’ai repris le code de ton « trigger ». Pour voir, j’ai créé la requête SQL suivante :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO Composer
    VALUES (8, 2, 'f8,m2');

    Puis je l’ai exécutée, et je me suis fait jeter :
     
     


    Achille, tu es le meilleur !
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  14. #94
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 620
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 620
    Points : 56 862
    Points
    56 862
    Billets dans le blog
    40
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Ok, Achille, pour Access, « Avant modification » ne veut pas dire « before update », ...
    Hé non, cela veut dire « before change », rien à voir... et tout cela est documenté.
    Au moins, cette data macro freinera la prolifération des monstres (pitié, un seul Hilarion par formation)...

    Citation Envoyé par escartefigue Voir le message
    Je vous suis de loin, il y a trop longtemps que je n'ai plus pratiqué MS Access, mais c'est très intéressant et mériterait sans doute un article ou un billet de blog
    Comme cette discussion atteindra bientôt la centaine de messages, et qu'elle a dû dériver plusieurs fois tel le pitalugue (ou l'Echo des îles), sur quel thème précisément tu verrais un article ou billet de blog ?

  15. #95
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 912
    Points
    38 912
    Billets dans le blog
    9
    Par défaut
    J'ai fait quelques recherches dans la section "MS Access" pour vérifier si le sujet avait déjà été abordé, mais sans succès.
    Peut-être que Claude Leloup, qui maîtrise bien Access, a tout de même déjà produit un article sur ce sujet.
    À défaut, un article sur la mise en œuvre des contraintes serait le bienvenu, me semble-t-il

  16. #96
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  17. #97
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 906
    Points
    30 906
    Billets dans le blog
    16
    Par défaut
    Ave,

    Citation Envoyé par Achille
    pitié, un seul Hilarion par formation...
    Certes, mais l’animal ne serait-il pas capable de contourner une telle contrainte ?
     
     
    Citation Envoyé par Le Capitaine
    un article sur la mise en œuvre des contraintes serait le bienvenu, me semble-t-il
    Pour ma part, comme vous avez pu vous en rendre compte, mes connaissances d’Access sont trop parcellaires pour me lancer. Une tentative à trois ?

    En attendant, à l’instar de Renaud Lavillenie et d’Armand Duplantis, histoire de monter la barre d’un cran, j’aimerais voir comment garantir les cardinalités minimales merisiennes 1 imposées par deedolith :
     
    Une formation est composée d’au moins un monstre et un montre entre dans la composition d’au moins une formation (cela valant même pour Hilarion).
     
     


    Achille, ton sentiment ?
     
     
    Merci User pour les liens.

    Christophe Warin a bien planté le décor il y a une quinzaine d’années, mais apparemment depuis ce temps-là, nihil novi... Dommage.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  18. #98
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 620
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 620
    Points : 56 862
    Points
    56 862
    Billets dans le blog
    40
    Par défaut
    Hop,

    Citation Envoyé par fsmrel Voir le message
    Pour ma part, comme vous avez pu vous en rendre compte, mes connaissances d’Access sont trop parcellaires pour me lancer. Une tentative à trois ?
    On peut essayer... Il faudrait partir d'un exemple simple et plus facilement accessible que ces histoires de monstres et de frénésies


    Citation Envoyé par fsmrel Voir le message
    Une formation est composée d’au moins un monstre et un montre entre dans la composition d’au moins une formation (cela valant même pour Hilarion).
    Garantir ces contraintes sous Access en dehors des formulaires et applicatifs en VBA ? Oulah. À la création d'une formation, la valider seulement si un monstre (qui n'existe peut-être pas encore) lui est associé, je donne ma langue au chat, mais ma pratique d'Access est aussi rouillée...

  19. #99
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 912
    Points
    38 912
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Pour ma part, comme vous avez pu vous en rendre compte, mes connaissances d’Access sont trop parcellaires pour me lancer. Une tentative à trois ?
    En l'occurrence sur ce sujet je serais certainement le cheval de trois, c'est à dire le cheval de trop ... qui du coup, file au galop !
    Et en pom-pom girl, je ne vaux guère plus

  20. #100
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 906
    Points
    30 906
    Billets dans le blog
    16
    Par défaut
    Ave,

    Vu l’enthousiasme unanime, je vais déjà voir de mon côté à faire une tentative avec SQL Server. J’aurais bien aimé me risquer avec DB2, mais ça fait 20 ans qu’on m’a ôté mon hochet préféré...

    Je vous tiendrai au courant.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

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

Discussions similaires

  1. Mettre en relation les contrôles DBLookUpComboBox et DBGrid
    Par Gendarmette dans le forum Bases de données
    Réponses: 7
    Dernier message: 19/01/2004, 13h16
  2. [Relations] afficher les relations entre 2 tables
    Par dzincou dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 14/01/2004, 17h07
  3. [EJB2.1 Entity] [CMR] Relation One to Many
    Par hamed dans le forum Java EE
    Réponses: 2
    Dernier message: 31/12/2003, 14h26
  4. Réponses: 2
    Dernier message: 26/09/2003, 15h54
  5. Problème avec mes tables de relation...
    Par mmike dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 02/06/2003, 15h16

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