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 :

Unable to create relationship 'FK_pets_owners'


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Février 2021
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2021
    Messages : 77
    Points : 51
    Points
    51
    Par défaut Unable to create relationship 'FK_pets_owners'
    Bonjour,

    J'utilise SSMS 18.11.1. J'ai deux tables avec les règles suivantes : un propriétaire peut avoir plus d'un animal. Un animal appartient à un seul propriétaire.

    table owners :
    --------------
    clé primaire nameID int
    name varchar(15)

    table pets :
    -----------
    clé primaire petsID int
    nameID int
    pets varchar(15)

    Lorsque je crée dans SSMS une relation de clé étrangère entre les tables 'pets' et 'owners' et que j'utilise l'option Cascade avec la règle Delete, j'obtiens cette erreur :

    'owners' table saved successfully
    'pets' table
    - Unable to create relationship 'FK_pets_owners'.
    Cascading foreign key 'FK_pets_owners' cannot be created where the referencing column 'pets.nameID' is an identity column.
    Could not create constraint or index. See previous errors.



    Maintenant, considérez cette base de données avec deux tables : produits et fournisseurs. Un fournisseur livre 1 ou plusieurs produits. Un produit est livré par un seul forunisseur.

    table products :
    ----------------
    clé primaire prodID int
    pname varchar(15)
    suppID int

    table suppliers :
    ----------------
    clé primaire suppID int
    sname varchar(15)


    Contrairement à la 1ère databse, ceci fonctionne parfaitement ! Je peux utiliser l'option cascade et je n'obtiens aucune erreur ! Pourquoi ça marche ici et pas avec l'autre ?

    Au fait, il est difficile d'imaginer qu'il ne soit pas possible de créer une contrainte de foreign key en cascade lorsque la colonne de référence est une colonne d'identité. C'est 99% des cas. Il n'y a pas d'autres champs communs pour le faire.

    Merci d'avance
    Romeo.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Citation Envoyé par romeo2003 Voir le message
    Pourquoi ça marche ici et pas avec l'autre ?
    Il semblerait que dans la table pets ce soit le nameId (du owner) qui porte la caractéristique identity au lieu de petsID.

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 130
    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 130
    Points : 38 543
    Points
    38 543
    Billets dans le blog
    9
    Par défaut
    IDENTITY permet de déléguer au SGBD le calcul de la valeur de la colonne concernée.
    C'est fréquemment utilisé pour les clefs primaires, car associé au type intéger, on satisfait deux critères essentiels d'une PK  : la stabilité et la concision.

    Comme dans la table pets, la colonne nameID est une clef étrangère faisant référence à la table owners, on ne peut évidemment pas laisser le SGBD en calculer la valeur, il faut récupérer la même valeur que celle attribuée au propriétaire de l'animal.

    Le mode opératoire est donc le suivant
    -1- insérer une ligne dans "owners" pour créer le propriétaire de l'animal en laissant SQL server calculer la valeur de nameID
    -2- récupérer cette valeur grâce à la fonction SCOPE_IDENTITY()
    -3- insérer une ligne dans "pets" pour créer l'animal, en laissant SQL server calculer la valeur de PetsID mais en alimentant nameID avec la valeur récupérée en -2-

    Note : l'usage est de nommer les tables et les colonnes au singulier : par exemple "owner" plutôt que "owners", on sait bien qu'une table peut contenir plusieurs occurrences . C'est d'autant plus vrai pour "PetID" plutôt que "PetsID", en effet, par définition, un identifiant c'est une et une seule occurrence !

  4. #4
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Février 2021
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2021
    Messages : 77
    Points : 51
    Points
    51
    Par défaut
    Merci pour l'explication. J'ai essayé ceci et ça marche.

    SqlConnection conn = new SqlConnection(connString);
    conn.Open();
    sql = "INSERT INTO owners (name) VALUES ('Bob');" + "select Scope_Identity()";
    comd = new SqlCommand(sql, conn);
    nr = Convert.ToInt32(comd.ExecuteScalar());

    sql = "INSERT INTO pets (petsname, nameID) VALUES ('Minou',@nr);";
    comd = new SqlCommand(sql, conn);
    comd.Parameters.AddWithValue("@nr", nr);
    comd.ExecuteNonQuery();
    conn.Close();

    En fait, on a besoin du Scope_Identity() que lorsqu'on veut insérer dans des tables connectées entre elles.

Discussions similaires

  1. Unable to create relationship
    Par debutantasp dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 31/07/2009, 11h31
  2. ORA-01658: unable to create INITIAL extent for segment in tablespace
    Par farenheiit dans le forum Administration
    Réponses: 11
    Dernier message: 05/06/2007, 17h49
  3. unable to create variable object
    Par Batou dans le forum C++
    Réponses: 2
    Dernier message: 09/05/2006, 07h49
  4. Réponses: 4
    Dernier message: 21/11/2005, 12h04
  5. unable to create INITIAL extent for segment in tablespace
    Par Ludolitaliano dans le forum Administration
    Réponses: 4
    Dernier message: 11/09/2003, 16h43

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