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

Développement SQL Server Discussion :

Peut-on faire une foreign key conditionelle ?


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 65
    Points : 43
    Points
    43
    Par défaut Peut-on faire une foreign key conditionelle ?
    Bonjour à tous

    j'ai 2 tables :
    Profs (idprof, nom, matiere...) ou matiere vaut SVT ou phys
    Classes (idclasse, nom, Profphys, profSVT...)

    je voudrais que Profsphys soit lié à l'idprof mais évidemment que les id des profs de phys

    j'ai essayé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CONSTRAINT [FK_Classes_ToTable] FOREIGN KEY ([Profphys]) REFERENCES (SELECT [idprof] FROM [Profs] WHERE matiere ='phys'))
    mais ça ne fonctionne pas

    Peut on utiliser un select comme référence ou il faut s'y prendre autrement ?

    D'avance merci pur votre temps.

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    C'est parce que votre modèle est incorrect.

    Un professeur enseigne au moins une (ou plus) matière.
    Les salles de cours ne sont pas dédiées qu'à une seule matière : une matière peut donc être enseignée dans plusieurs salles.

    Donc vous devriez avoir une entité classe, une entité professeur, et une entité matière.
    A partir de là, vous allez voir que ce que vous souhaitez réaliser est en fait très simple

    Tenez-nous au courant !

    @++

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 65
    Points : 43
    Points
    43
    Par défaut
    Bonjour Elsuket

    merci pour votre réponse.

    petite précision :

    - un prof n'enseigne qu'une matière.
    - Je pense que vous avez pris ma table "Classe" pour une salle de classe alors qu'elle représente un niveau (1ere terminale...)
    à partir de là, chaque classe a un prof de phys et un de SVT qu'il doit choisir dans la table prof mais je veux contrôler que l'utilisateur
    n'entre pas un id d'un prof de physique pour un prof de SVT et vice et versa.

    je ne vois pas en quoi la création d'une table matiere solutionne mon problème.

    si j'ai
    Profs (idprof, nom, matiereprof...)
    Classes (idclasse, nom, Profphys, profSVT...)
    Matiere(nom_matiere) avec 2 éléments ds la table (phys et SVT)

    j'ajoute une foreign key
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CONSTRAINT [FK1] FOREIGN KEY ([matierprof]) REFERENCES [Matiere]([nom_matiere])
    mais j'ai toujours le même problème pour la 2ème référence de la FK.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CONSTRAINT [FK2] FOREIGN KEY ([Profphys]) REFERENCES ??????????????????,
    La seule "solution" que j'ai trouvé, c'est de faire 2 tables : Profsphysique et ProfsSVT et de faire des unions quand je veux la liste entière, mais ça me parait être une fausse bonne idée.

  4. #4
    Membre expert
    Avatar de mail.spam
    Homme Profil pro
    Développeur Windev et technicien maintenance
    Inscrit en
    Janvier 2008
    Messages
    1 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Windev et technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2008
    Messages : 1 914
    Points : 3 803
    Points
    3 803
    Par défaut
    Bonjour,
    Il te faut une troisième table.
    qui se compose de annee, idprof et id classe
    Chaque ligne de la table te permettra de lister pour chaque année les classes et les profs.
    puis en fesant ta requête a partir de cette table et en lien avec les autres tu auras toutes tes infos
    la touche est ton amie. l'aide ne mord pas quand on la consulte...
    PS : n'oubliez jamais que nous ne sommes pas avec vous sur le projet. Donc plus vous donnez d'informations et d'exemples de codes et plus nous pourrons vous aider. (Un exemple vaut mieux que de longs discours...)

    Pensez à utiliser les votes et à cliquer sur , merci

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 65
    Points : 43
    Points
    43
    Par défaut
    Bonjour

    merci, mais votre réponse ne correspond pas du tout à la question posée. Je ne vois pas du tout l’intérêt d'ajouter les années dans l'histoire.

    Je donne un exemple car mon explication n'a pas l'air d'être claire.

    table Profs (idprof, nom, matiere...) contient
    1 TOTO phys
    2 TUTU SVT
    3 TITI SVT
    4 TATA phys

    Quand l'utilisateur remplit la table Classes (idclasse, nom, Profphys, profSVT...) pour La Terminale1

    il rentre : 1, terminale1, X ,Y mais je veux que X = 1 ou 4 et Y = 2 ou 3 pour empêcher l'utilisateur de rentrer un id de prof de physique dans la colonne profSVT.

  6. #6
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    votre réponse ne correspond pas du tout à la question posée
    Peut-être ... disons que nous n'avez pas donné le contexte de votre application, ce qui fait que ma première réponse non plus ne correspond pas à ce que vous recherchez.
    En tout cas je trouve que la suggestion de mail.spam n'est pas dénuée de sens, étant donné que les professeurs et les matières qu'ils enseignent peuvent changer.

    Vous avez limité votre problème aux professeurs de Physique-Chimie et de SVT, mais en fait c'est applicable à tout professeur.
    En effet, une classe telle que vous l'avez définie n'a toujours qu'un seul professeur qui enseigne une matière, qui peut aussi être les Mathématiques, le Français, l'Histoire, ...

    Dès lors une entité matière s'impose, tout comme la classe.
    L'entité professeur référence l'entité matière. Il suffit ensuite de rajouter une relation entre la classe et les professeurs.

    La contrainte que vous ajoutez, par laquelle un professeur ne peut enseigner qu'une seule matière, et la classe assiste à ces matières, est implémentable à l'aide d'une une contrainte de domaine.

    Vous noterez que je n'ai pas mis d'attribut de nom à l'entité professeur, parce qu'un professeur fait partie du personnel de établissement d'enseignement.
    Dès lors, un professeur a des attributs spécifiques relatifs à sa discipline, et il se peut qu'il soit aussi proviseur, par exemple.
    Par conséquent, l'entité professeur ne serait qu'une spécialisation d'une autre entité, que l'on pourrait appeler personne.
    Par ailleurs, j'ai considéré que l'établissement n'a qu'une seule classe pour chaque niveau.

    Physiquement, cela se traduit comme suit :

    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
    CREATE TABLE dbo.matiere
    (
    	id_matiere tinyint NOT NULL IDENTITY(0,1)
    		CONSTRAINT PK_matiere PRIMARY KEY
    	, nom_matiere varchar(64) NOT NULL
    		CONSTRAINT UQ_matiere__nom_matiere UNIQUE
    )
    GO
     
    INSERT INTO dbo.matiere
    (
    	nom_matiere
    )
    VALUES ('Physique-Chimie')
    	, ('Sciences et Vie de la Terre')
    GO
     
    CREATE TABLE dbo.professeur
    (
    	id_professeur smallint NOT NULL IDENTITY
    		CONSTRAINT PK_professeur PRIMARY KEY
    	, licence_professeur varchar(16) NOT NULL
    		CONSTRAINT UQ_professeur__licence_professeur UNIQUE
    	, id_matiere tinyint NOT NULL
    		CONSTRAINT FK_professeur__id_matiere
    		FOREIGN KEY (id_matiere) REFERENCES dbo.matiere
    )
    GO
     
    INSERT INTO dbo.professeur
    (
    	licence_professeur
    	, id_matiere
    )
    VALUES	('PC2015-001', 0)
    	, ('SVT2014-001', 1)
    	, ('PC2015-002', 0)
    	, ('SVT2015-001', 1)
    GO
     
    CREATE TABLE dbo.classe
    (
    	id_classe int NOT NULL IDENTITY
    		CONSTRAINT PK_classe PRIMARY KEY
    	, nom_classe varchar(16)
    		CONSTRAINT UQ_classe__nom_classe UNIQUE
    )
    GO
     
    INSERT INTO dbo.classe
    (
    	nom_classe
    )
    VALUES ('Seconde'), ('Première'), ('Terminale')
    GO
     
    CREATE TABLE dbo.classe_professeur
    (
    	id_classe_professeur int NOT NULL IDENTITY
    		CONSTRAINT PK_classe_professeur PRIMARY KEY
    	, id_classe int NOT NULL
    		CONSTRAINT FK_classe_professeur__id_classe
    		FOREIGN KEY (id_classe) REFERENCES dbo.classe
    	, id_professeur smallint NOT NULL
    		CONSTRAINT FK_classe_professeur__id_professeur
    		FOREIGN KEY (id_professeur) REFERENCES dbo.professeur
    	, CONSTRAINT UQ_classe_professeur__id_classe__id_professeur
    		UNIQUE (id_classe, id_professeur)
    )
    GO
     
    CREATE FUNCTION fn_check_classe_professeur
    	(
    		@_id_classe int
    		, @id_professeur smallint
    	)
    RETURNS bit
    WITH SCHEMABINDING
    AS
    BEGIN
    	DECLARE @ok bit = 1;
     
    	IF EXISTS
    	(
    		SELECT		CP.id_classe
    					, M.id_matiere
    		FROM		dbo.classe_professeur AS CP
    		INNER JOIN	dbo.professeur AS P
    					ON P.id_professeur = CP.id_professeur
    		INNER JOIN	dbo.matiere AS M
    					ON P.id_matiere = M.id_matiere
    		GROUP BY	CP.id_classe, M.id_matiere HAVING COUNT(*) > 1
    	)
    	BEGIN
    		SET @ok = 0;
    	END
     
    	RETURN @ok;
    END
    GO
     
    ALTER TABLE dbo.classe_professeur
    ADD CONSTRAINT CHK_classe_professeur__id_classe__id_professeur
    	CHECK (dbo.fn_check_classe_professeur(id_classe, id_professeur) = 1)
    GO
    Un exemple d'utilisation est le suivant : le premier INSERT s'exécute sans problème; le second échoue car il viole la contrainte de domaine CHK_classe_professeur__id_classe__id_professeur, puisque les professeurs d'id 1 et 3 sont tous deux professeurs de Physique-Chimie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    INSERT INTO dbo.classe_professeur
    (
    	id_classe
    	, id_professeur
    )
    VALUES (1, 1)
    GO
     
    INSERT INTO dbo.classe_professeur
    (
    	id_classe
    	, id_professeur
    )
    VALUES (1, 3)
    @++

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 65
    Points : 43
    Points
    43
    Par défaut
    Bonjour Elsuket

    merci beaucoup pour votre réponse et votre temps.

    Je ne connaissais pas la possibilité de créer des fonctions qui servaient de contrainte. Je n'ai pas encore tout compris mais j'étudie votre code avec grand intérêt.

    Vous avez limité votre problème aux professeurs de Physique-Chimie et de SVT, mais en fait c'est applicable à tout professeur.
    En effet, une classe telle que vous l'avez définie n'a toujours qu'un seul professeur qui enseigne une matière, qui peut aussi être les Mathématiques, le Français, l'Histoire, ...
    En fait non, j’essaie de faire une application pour l'organisation des ECE (capacités expérimentales) au BAC donc ça ne touche que les profs de phys et de SVT, que les classes de Terminale S.
    L'année suivante, on vide tout et on recommence donc pas besoin d'historique.

    Mon projet est donc très très restreint par rapport à votre imagination et votre recul professionnel.

    Merci encore

  8. #8
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    En fait non, j’essaie de faire une application pour l'organisation des ECE (capacités expérimentales) au BAC donc ça ne touche que les profs de phys et de SVT, que les classes de Terminale S.
    L'année suivante, on vide tout et on recommence donc pas besoin d'historique.

    Mon projet est donc très très restreint par rapport à votre imagination et votre recul professionnel.
    Merci de votre retour. Si vous avez des questions ou des remarques n'hésitez pas.

    Définissez bien votre problème (c'est-à-dire le contexte) avant de passer à la solution.
    Si vous n'avez pas encore travaillé en tant qu'informaticien avec des gens non-informaticiens, vous remarquerez que c'est récurrent

    @++

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

Discussions similaires

  1. Peut-on faire une API avec Delphi ?
    Par WebPac dans le forum API, COM et SDKs
    Réponses: 14
    Dernier message: 11/04/2023, 14h48
  2. Réponses: 2
    Dernier message: 30/03/2007, 09h43
  3. Une Foreign Key peut-elle être null ?
    Par bassim dans le forum Firebird
    Réponses: 9
    Dernier message: 21/11/2006, 20h20
  4. suppression d'une foreign key
    Par GMI dans le forum InterBase
    Réponses: 7
    Dernier message: 01/02/2005, 11h07
  5. [débutant] Aide pour mettre une FOREIGN KEY sur une table
    Par cauldron dans le forum Langage SQL
    Réponses: 2
    Dernier message: 14/11/2004, 17h16

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