web-dev-qa-db-fra.com

Clé étrangère référençant une clé primaire à 2 colonnes dans SQL Server

Cette question est assez semblable à celle-ci , mais pour SQL Server 2005:

J'ai 2 tables dans ma base de données:

--'#' denotes the primary key
[Libraries]
#ID   #Application  Name
 1     MyApp        Title 1
 2     MyApp        Title 2


[Content]
#ID   Application  LibraryID  Content
 10    MyApp       1          xxx
 11    MyApp       1          yyy

(la base de données est évidemment beaucoup plus complexe et avoir cette double clé est logique)

Chaque bibliothèque est identifiée par son identifiant unique et son nom d'application. J'essaie de m'assurer que chaque contenu fait correctement référence à une bibliothèque existante.

Lors de la création de la contrainte (à l'aide de l'assistant) en tant que

Primary key table            Foreign key table
[Libraries]                  [Content]
ID                  --->     LibraryID
Application         --->     Application

J'ai l'erreur suivante: 

Les colonnes du tableau 'Bibliothèques' font ne correspond pas à une clé primaire existante ou Contrainte unique

Avez-vous une idée de ce qui se passe? et si c'est possible du tout en utilisant SQL Server? (Je ne peux pas du tout modifier la table [Bibliothèque])

Merci beaucoup pour votre aide!

23
Luk

Bien sûr, il est possible de créer une relation de clé étrangère avec une clé primaire composée (plus d'une colonne). Vous ne nous avez pas montré la déclaration que vous utilisez pour essayer de créer cette relation - cela devrait être quelque chose comme:

ALTER TABLE dbo.Content
   ADD CONSTRAINT FK_Content_Libraries
   FOREIGN KEY(LibraryID, Application)
   REFERENCES dbo.Libraries(ID, Application)

Est-ce ce que vous utilisez ?? Si (ID, Application) est bien la clé primaire sur dbo.Libraries, cette instruction devrait fonctionner.

Luk: juste pour vérifier - pouvez-vous exécuter cette instruction dans votre base de données et rendre compte de la sortie?

SELECT
    tc.TABLE_NAME,
    tc.CONSTRAINT_NAME, 
    ccu.COLUMN_NAME
FROM 
    INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
INNER JOIN 
    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu 
      ON ccu.TABLE_NAME = tc.TABLE_NAME AND ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
WHERE
    tc.TABLE_NAME IN ('Libraries', 'Content')
40
marc_s

Notez que les champs doivent être dans le même ordre. Si la clé primaire que vous référencez est spécifiée comme (Application, ID), votre clé étrangère doit alors être référencée (Application, ID) et NOT (ID, Application) car elles sont considérées comme deux clés différentes.

7
Will Russell

La clé est "l'ordre de la colonne doit être le même"

Exemple:

create Table A (
    A_ID char(3) primary key,
    A_name char(10) primary key,
    A_desc desc char(50)
)

create Table B (
    B_ID char(3) primary key,
    B_A_ID char(3),
    B_A_Name char(10),
    constraint [Fk_B_01] foreign key (B_A_ID,B_A_Name) references A(A_ID,A_Name)
)

l'ordre des colonnes sur la table A devrait être -> A_ID puis A_Name; la définition de la clé étrangère doit également suivre le même ordre.

1
danny

La table Content est susceptible de contenir plusieurs valeurs Application en double qui ne peuvent pas être mappées sur Libraries. Est-il possible de supprimer la colonne Application de l'index de clé primaire Libraries et de l'ajouter en tant qu'index de clé unique?

1
Adrian Godong

J'ai eu le même problème et je pense avoir la solution.

Si votre champ Application dans la table Library a une clé étrangère qui référence un champ dans une autre table (nommé Application je parierais), votre champ Application dans la table Library doit également avoir une clé étrangère dans la table Application.

Après cela, vous pouvez faire votre clé étrangère composée.

Excuse mon pauvre anglais, et désolé si je me trompe.

0
Alex France