Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 21/07/2009, à 11:59

amwus

[Résolu] Encore un probleme HSQLDB...

Salut les gens... J'ai un soucis lors de la création d'une base HSQLDB... Je pense que mes commandes de créations sont correctes, mais visiblement, ça n'est pas le cas... Quelqu'un pourrait il me dire où se trouve l'erreur ?

Merci...

Voici le script de création et l'erreur obtenues :

/* Table CLASSE */
    dbManagement.executeSQLCommand("CREATE TABLE classe (" +
                                   "num INT GENERATED BY DEFAULT AS IDENTITY " +
                                   "(START WITH 1) PRIMARY KEY," +
                                   "nom_classe VARCHAR(50))");
    
    /* Table COMPETENCE */
    dbManagement.executeSQLCommand("CREATE TABLE competence (" +
                                   "nom_compet VARCHAR(100) " +
                                   "PRIMARY KEY)");
    
    /* Table INTERRO */
    dbManagement.executeSQLCommand("CREATE TABLE interro (" +
                                   "date_interro DATE, " +
                                   "nom_interro VARCHAR(50)," +
                                   "CONSTRAINT keyInterro " +
                                   "PRIMARY KEY (date_interro, nom_interro))");
    
    /* Table ELEVE */
    dbManagement.executeSQLCommand("CREATE TABLE eleve (" +
                                   "id_eleve INT GENERATED BY DEFAULT " +
                                   "AS IDENTITY (START WITH 1) PRIMARY KEY," +
                                   "nom_eleve VARCHAR(50)," +
                                   "prenom_eleve VARCHAR(50)," +
                                   "num_classe INT," +
                                   "FOREIGN KEY (num_classe) REFERENCES " +
                                   "classe(num))");
    
    /* Table PASSE */
    dbManagement.executeSQLCommand("CREATE TABLE passe (" +
                                   "id_eleve INT," +
                                   "nom_interro VARCHAR(50)," +
                                   "date_interro DATE," +
                                   "resultat REAL," +
                                   "FOREIGN KEY (id_eleve) REFERENCES " +
                                   "eleve(id_eleve)," +
                                   "FOREIGN KEY (nom_interro) REFERENCES " +
                                   "interro (nom_interro)," +
                                   "FOREIGN KEY (date_interro) REFERENCES " +
                                   "interro(date_interro), " +
                                   "CONSTRAINT keyPasse " +
                                   "PRIMARY KEY (id_eleve, " +
                                   "nom_interro, date_interro))");
    
    /* Table REMPLIT */
    dbManagement.executeSQLCommand("CREATE TABLE remplit (" +
                                   "nom_competence VARCHAR(50)," +
                                   "nom_interro VARCHAR(50)," +
                                   "date_interro DATE," +
                                   "FOREIGN KEY (nom_competence) REFERENCES" +
                                   "competence(nom_compet)," +
                                   "FOREIGN KEY (nom_interro) REFERENCES" +
                                   "interro (nom_interro)," +
                                   "FOREIGN KEY (date_interro) REFERENCES" +
                                   "interro (date_interro)," +
                                   "CONSTRAINT keyRemplit " +
                                   "PRIMARY KEY (nom_comptence, nom_interro," +
                                   "date_interro))");

Erreur obtenue :

Creating initial database...
java.sql.SQLException: Primary or unique constraint required on main table: INTERRO in statement [CREATE TABLE passe (id_eleve INT,nom_interro VARCHAR(50),date_interro DATE,resultat REAL,FOREIGN KEY (id_eleve) REFERENCES eleve(id_eleve),FOREIGN KEY (nom_interro) REFERENCES interro (nom_interro),FOREIGN KEY (date_interro) REFERENCES interro(date_interro), CONSTRAINT keyPasse PRIMARY KEY (id_eleve, nom_interro, date_interro))]
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
    at org.hsqldb.jdbc.jdbcStatement.executeUpdate(Unknown Source)
    at database.ManageDatabase.executeSQLCommand(ManageDatabase.java:33)
    at database.CreateInitialDB.createTables(CreateInitialDB.java:66)
    at database.CreateInitialDB.<init>(CreateInitialDB.java:18)
    at SchoolData.main(SchoolData.java:48)

Je ne trouve personne qui puisse m'aider sur ce sujet... Apparemment, HSQL n'est pas très connu des développeurs !
Merci encore ! cool

Dernière modification par amwus (Le 21/07/2009, à 18:13)


Black holes are where god divided by zero...

Hors ligne

#2 Le 21/07/2009, à 12:14

Khyl

Re : [Résolu] Encore un probleme HSQLDB...

Je vois déjà un truc qui ne va pas dans ta table passe

/* Table PASSE */
    dbManagement.executeSQLCommand("CREATE TABLE passe (" +
                                   "id_eleve INT," +
                                   "nom_interro VARCHAR(50)," +
                                   "date_interro DATE," +
                                   "resultat REAL," +
                                   "FOREIGN KEY (id_eleve) REFERENCES " +
                                   "eleve(id_eleve)," +
                                   "FOREIGN KEY (nom_interro) REFERENCES " +
                                   "interro (nom_interro)," +
                                   "FOREIGN KEY (date_interro) REFERENCES " +
                                   "interro(date_interro), " +
                                   "CONSTRAINT keyPasse " +
                                   "PRIMARY KEY (id_eleve, " +
                                   "nom_interro, date_interro))");

pour les foreign key, ce sont aussi des contraintes d'intégrité donc il faut aussi faire précéder par CONSTRAINT suivi d'un nom de contrainte.

Dernière modification par Khyl (Le 21/07/2009, à 12:14)

Hors ligne

#3 Le 21/07/2009, à 12:34

amwus

Re : [Résolu] Encore un probleme HSQLDB...

Ha bon ? Je n'ai jamais fais ça en SQL "classique"... Mais je suis assez nouveau dans le monde des bases de données donc c'est possible... Il faudrait donc que je fasse quelque chose du genre

CONSTRAINT foreignIdEleve FOREIGN KEY (id_eleve) REFERENCES eleve(id_eleve)

Pour chaque foreign key ?


Black holes are where god divided by zero...

Hors ligne

#4 Le 21/07/2009, à 14:11

Khyl

Re : [Résolu] Encore un probleme HSQLDB...

C'est ça smile

Regarde ce document d'aide sur hsql au niveau du create table, tu vas voir c'est indiqué.
Pour les contraintes d'intégrité concernant la clé primaire, tu peux écrire par exemple :

create table test (
champ1 int primary key,
champ2 date)

Ca c'est dans le cas où ta clé primaire est sur un seul champ. Sinon si elle est sur plusieurs champs, il faut passer par Constraint comme tu l'as fait.
Par contre pour les clés étrangères, il faut forcément passer par constraint car il faut préciser à quelle table chacunes sont attachées.

Dernière modification par Khyl (Le 21/07/2009, à 14:14)

Hors ligne

#5 Le 21/07/2009, à 14:16

amwus

Re : [Résolu] Encore un probleme HSQLDB...

Moui... ça ne change rien à mon probleme... J'ai toujours exactement le même probleme... C'est bizarre... Quand même, mySQL c'est plus simple ! big_smile


Black holes are where god divided by zero...

Hors ligne

#6 Le 21/07/2009, à 14:41

Khyl

Re : [Résolu] Encore un probleme HSQLDB...

Tu as de nouveau le même message d'erreur sur la même table ?

Hors ligne

#7 Le 21/07/2009, à 14:43

amwus

Re : [Résolu] Encore un probleme HSQLDB...

Oui... Et j'ai essayé différemment, en modifiant la table à l'aide de ALTER TABLE et ça redonne exactement le meme probleme...

Voila ce que j'ai fait pour cette table :

/* Table PASSE */
    dbManagement.executeSQLCommand("CREATE TABLE passe (" +
                                   "id_eleve INT," +
                                   "nom_interro VARCHAR(50)," +
                                   "date_interro DATE," +
                                   "resultat REAL)");
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " +
                                   "fIdEleve FOREIGN KEY (id_eleve) " +
                                   "REFERENCES eleve(id_eleve)");
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " +
                                   "fNomInterro FOREIGN KEY (nom_interro) " +
                                   "REFERENCES interro (nom_interro)");
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " +
                                   "fDateInterro FOREIGN KEY (date_interro) " +
                                   "REFERENCES interro(date_interro)");
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " + 
                                   "keyPasse "PRIMARY KEY (id_eleve, " +
                                   "nom_interro, date_interro)");

Pourtant d'après la doc officielle, ça me parait correct... Il doit y avoir un autre probleme...

Dernière modification par amwus (Le 21/07/2009, à 14:46)


Black holes are where god divided by zero...

Hors ligne

#8 Le 21/07/2009, à 15:04

Khyl

Re : [Résolu] Encore un probleme HSQLDB...

haaa très propre ce que tu as écrit là, j'aime beaucoup, c'est bien mieux que la version précédente, il vaut mieux faire un create table puis des alter table avec les contraintes d'intégrité donc ça c'est très bien.

Par contre en effet je vois qu'on a pas répondu à l'erreur "Primary or unique constraint required on main table: INTERRO"

Dans la table interro, tu as une clé primaire qui est sur 2 champs (nom_interro et date_interro) or ta clé étrangère n'appelle qu'un seul de ses champs à la fois donc je pense que c'est ça qu'il n'aime pas.

Mon bon conseil : dans la table interro, tu devrais mettre une clé sur un identifiant

create table interro (
id_interro int primary key,
nom_interro varchar(50),
date_interro date)

create table passe (
id_eleve int,
id_interro int,
resultat REAL)

alter table passe add constraint idInterro foreign key (id_interro)  references interro(id_interro)

Comme ça tu identifies bien la clé primaire de la table interro et pour y accéder, c'est très simple, tu as la clé étrangère dans la table passe donc tu retrouves le nom et la date de l'interrogation.
Tu vois ce que je veux dire ? je pense que non seulement ça va résoudre ton problème mais en plus ça sera beaucoup plus propre au niveau base de données.

Dernière modification par Khyl (Le 21/07/2009, à 15:07)

Hors ligne

#9 Le 21/07/2009, à 15:44

amwus

Re : [Résolu] Encore un probleme HSQLDB...

He ben, c'est gagné ! Ca fonctionne comme ça. J'ai du un peu modifier d'autres tables pour les adapter, mais je pense qu'au final, cela ne change rien à la base de données !

Voici ce que j'ai maintenant :

/* Table CLASSE */
    dbManagement.executeSQLCommand("CREATE TABLE classe (" +
                                   "num INT GENERATED BY DEFAULT AS IDENTITY " +
                                   "(START WITH 1) PRIMARY KEY," +
                                   "nom_classe VARCHAR(50))");
    
    /* Table COMPETENCE */
    dbManagement.executeSQLCommand("CREATE TABLE competence (" +
                                   "nom_compet VARCHAR(100) " +
                                   "PRIMARY KEY)");
    
    /* Table INTERRO */
    dbManagement.executeSQLCommand("CREATE TABLE interro (" +
                                   "id_interro INT GENERATED BY DEFAULT " +
                                   "AS IDENTITY (START WITH 1) PRIMARY KEY," +                                   
                                   "date_interro DATE, " +
                                   "nom_interro VARCHAR(50))");                                 
    
    /* Table ELEVE */
    dbManagement.executeSQLCommand("CREATE TABLE eleve (" +
                                   "id_eleve INT GENERATED BY DEFAULT " +
                                   "AS IDENTITY (START WITH 1) PRIMARY KEY," +
                                   "nom_eleve VARCHAR(50)," +
                                   "prenom_eleve VARCHAR(50)," +
                                   "num_classe INT)");
    
    dbManagement.executeSQLCommand("ALTER TABLE eleve ADD CONSTRAINT " +
                                   "fNumClass FOREIGN KEY (num_classe) " +
                                   "REFERENCES classe(num)");
    
    /* Table PASSE */
    dbManagement.executeSQLCommand("CREATE TABLE passe (" +
                                   "id_eleve INT, id_interro INT, " +
                                   "resultat REAL)");
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " +
                                   "fIdEleve FOREIGN KEY (id_eleve) " +
                                   "REFERENCES eleve(id_eleve)");
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " +
                                   "fIdInterro FOREIGN KEY (id_interro) " +
                                   "REFERENCES interro (id_interro)");    
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " + 
                                   "keyPasse PRIMARY KEY (id_eleve, " +
                                   "id_interro)");
    
    /* Table REMPLIT */
    dbManagement.executeSQLCommand("CREATE TABLE remplit (" +
                                   "nom_competence VARCHAR(50)," +
                                   "id_interro INT)");
    
    dbManagement.executeSQLCommand("ALTER TABLE remplit ADD CONSTRAINT " +
                                   "fNomCompet FOREIGN KEY (nom_competence) " +
                                   "REFERENCES competence(nom_compet)");
    
    dbManagement.executeSQLCommand("ALTER TABLE remplit ADD CONSTRAINT " +
                                   "forIdInterro FOREIGN KEY (id_interro) " +
                                   "REFERENCES interro (id_interro)");
    
    dbManagement.executeSQLCommand("ALTER TABLE remplit ADD CONSTRAINT " +
                                   "keyRemplit PRIMARY KEY (nom_competence, " +
                                   "id_interro)");

Juste une petite question, quand je veux accéder aux clés des tables, si elles sont FOREIGN KEY, est ce que je dois utiliser le nom de la contrainte (exemple keyRemplit) ou le nom "normal" de la colonne ?

En tout cas, merci pour ton aide !
smile


Black holes are where god divided by zero...

Hors ligne

#10 Le 21/07/2009, à 16:05

amwus

Re : [Résolu] Encore un probleme HSQLDB...

Zut, maintenant la base de données se crée bien, mais lorsque j'essaie de me connecter à la DB pour l'utiliser j'obtiens une erreur ! Comprend pas...

Décidément, ça ne va pas aujourd'hui !

Voici l'erreur obtenue lors de la connexion à la DB :

Normal mode.
java.sql.SQLException: error in script file line: 6 Constraint already exists: FORIDELEVE in statement [CREATE MEMORY TABLE PASSE(ID_ELEVE INTEGER NOT NULL,ID_INTERRO INTEGER NOT NULL,RESULTAT REAL,CONSTRAINT FORIDELEVE PRIMARY KEY(ID_ELEVE,ID_INTERRO),CONSTRAINT FORIDELEVE FOREIGN KEY(ID_ELEVE) REFERENCES ELEVE(ID_ELEVE),CONSTRAINT FORIDINTERRO FOREIGN KEY(ID_INTERRO) REFERENCES INTERRO(ID_INTERRO))]
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.jdbcConnection.<init>(Unknown Source)
    at org.hsqldb.jdbcDriver.getConnection(Unknown Source)
    at org.hsqldb.jdbcDriver.connect(Unknown Source)
    at java.sql.DriverManager.getConnection(DriverManager.java:582)
    at java.sql.DriverManager.getConnection(DriverManager.java:185)
    at SchoolData.main(SchoolData.java:72)

Qu'en penses tu ?

Merci...


Black holes are where god divided by zero...

Hors ligne

#11 Le 21/07/2009, à 16:07

Khyl

Re : [Résolu] Encore un probleme HSQLDB...

Tu utilises le nom normal de la colonne, par exemple tu peux faire une requête du genre

select nom_interro, date_interro, resultat
from passe, interro
where passe.id_interro = interro.id_interro

Voilà, on a réussi car tu as toi aussi été très réactif. Au plaisir de t'aider à nouveau

Hors ligne

#12 Le 21/07/2009, à 16:10

Khyl

Re : [Résolu] Encore un probleme HSQLDB...

regarde bien, tu as FORIDELEVE deux fois dans ta table passe

CONSTRAINT FORIDELEVE PRIMARY KEY(ID_ELEVE,ID_INTERRO),CONSTRAINT FORIDELEVE FOREIGN KEY(ID_ELEVE) REFERENCES ELEVE(ID_ELEVE)

Il faut mettre des noms différents pour chaque contrainte d'intégrité tongue

Dernière modification par Khyl (Le 21/07/2009, à 16:12)

Hors ligne

#13 Le 21/07/2009, à 16:14

amwus

Re : [Résolu] Encore un probleme HSQLDB...

Justement, dans mon script de création, il n'apparait pas deux fois, mais bizarrement, il apparait 2 fois dans fichier de DB...

Bref, j'ai réussi à régler le probleme en mettant les PRIMARY KEY directement dans la définition de la table, avant les FOREIGN KEY donc... Mais est ce correct de faire comme ça ?

Voici ma base de donnée finale qui ne me génère plus aucune erreur... Tu confirmes que ça ne change rien par rapport à ci-dessus ?

/* Table CLASSE */
    dbManagement.executeSQLCommand("CREATE TABLE classe (" +
                                   "num_classe INT GENERATED BY DEFAULT " +
                                   "AS IDENTITY (START WITH 1) PRIMARY KEY," +
                                   "nom_classe VARCHAR(50))");
    
    /* Table COMPETENCE */
    dbManagement.executeSQLCommand("CREATE TABLE competence (" +
                                   "nom_compet VARCHAR(100) " +
                                   "PRIMARY KEY)");
    
    /* Table INTERRO */
    dbManagement.executeSQLCommand("CREATE TABLE interro (" +
                                   "id_interro INT GENERATED BY DEFAULT " +
                                   "AS IDENTITY (START WITH 1) PRIMARY KEY, " +                                   
                                   "date_interro DATE, " +
                                   "nom_interro VARCHAR(50))");                                 
    
    /* Table ELEVE */
    dbManagement.executeSQLCommand("CREATE TABLE eleve (" +
                                   "id_eleve INT GENERATED BY DEFAULT " +
                                   "AS IDENTITY (START WITH 1) PRIMARY KEY," +
                                   "nom_eleve VARCHAR(50)," +
                                   "prenom_eleve VARCHAR(50)," +
                                   "num_classe INT)");
    
    dbManagement.executeSQLCommand("ALTER TABLE eleve ADD CONSTRAINT " +
                                   "forNumClass FOREIGN KEY (num_classe) " +
                                   "REFERENCES classe(num_classe)");
    
    /* Table PASSE */
    dbManagement.executeSQLCommand("CREATE TABLE passe (" +
                                   "id_eleve INT, id_interro INT, " +
                                   "resultat REAL, " +
                                   "CONSTRAINT keyPasse PRIMARY KEY " +
                                   "(id_eleve, id_interro))");
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " +
                                   "forIdEleve FOREIGN KEY (id_eleve) " +
                                   "REFERENCES eleve(id_eleve)");
    
    dbManagement.executeSQLCommand("ALTER TABLE passe ADD CONSTRAINT " +
                                   "forIdInterro FOREIGN KEY (id_interro) " +
                                   "REFERENCES interro (id_interro)"); 
    
    /* Table REMPLIT */
    dbManagement.executeSQLCommand("CREATE TABLE remplit (" +
                                   "nom_competence VARCHAR(50)," +
                                   "id_interro INT, " +
                                   "CONSTRAINT keyRemplit PRIMARY KEY " +
                                   "(nom_competence, id_interro))");
    
    dbManagement.executeSQLCommand("ALTER TABLE remplit ADD CONSTRAINT " +
                                   "fNomCompet FOREIGN KEY (nom_competence) " +
                                   "REFERENCES competence(nom_compet)");
    
    dbManagement.executeSQLCommand("ALTER TABLE remplit ADD CONSTRAINT " +
                                   "forIdInterroR FOREIGN KEY (id_interro) " +
                                   "REFERENCES interro (id_interro)");

Merci !


Black holes are where god divided by zero...

Hors ligne

#14 Le 21/07/2009, à 16:17

Khyl

Re : [Résolu] Encore un probleme HSQLDB...

C'est nickel, bien joué, tu as fait du bon boulot.

Hors ligne

#15 Le 21/07/2009, à 16:50

amwus

Re : [Résolu] Encore un probleme HSQLDB...

Merci de ton aide !

Ca fait plaisir de rencontrer des gens qui rendent service avec plaisir wink


Black holes are where god divided by zero...

Hors ligne