2010-07-05 7 views
16

Diese Frage zu this one ziemlich ähnlich ist, aber für SQL Server 2005:Fremdschlüssel ein 2 Spalten Primärschlüssel in SQL Server verweisen

Ich habe 2 Tabellen in meiner Datenbank:

--'#' 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 

(die Datenbank ist offensichtlich viel komplexer und mit diesem doppelten Schlüssel ist sinnvoll)

Jede Bibliothek wird durch seine eindeutige ID und Anwendungsname identifiziert. Ich versuche sicherzustellen, dass jeder Inhalt ordnungsgemäß auf eine vorhandene Bibliothek verweist.

Wenn die Einschränkung der Erstellung (mit dem Assistenten) als

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

Ich habe folgende Fehlermeldung:

The columns in table 'Libraries' do not match an existing primary key or UNIQUE constraint

Haben Sie eine Vorstellung davon, was los ist? und wenn es mit SQL Server überhaupt möglich ist? (Ich kann die [Bibliothek] Tabelle überhaupt nicht ändern)

Vielen Dank für Ihre Hilfe!

Antwort

33

Natürlich ist es möglich, eine Fremdschlüsselbeziehung zu einem zusammengesetzten Primärschlüssel (mehr als eine Spalte) zu erstellen. Sie zeigten uns nicht die Aussage, die Sie verwenden, diese Beziehung zu versuchen und schaffen - es sollte so etwas wie:

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

Ist das, was Sie verwenden ?? Wenn (ID, Application) tatsächlich der Primärschlüssel auf dbo.Libraries ist, sollte diese Anweisung definitiv funktionieren.

Luk: nur um zu überprüfen - können Sie diese Aussage in Ihrer Datenbank laufen und berichten, was die Ausgabe ist?

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') 
+0

Ich habe die Benutzeroberfläche direkt an diesem Punkt verwendet, aber die Verwendung Ihrer Syntax löst den folgenden Fehler aus: "In der referenzierten Tabelle 'dbo.Libraries' gibt es keine Primär- oder Kandidatenschlüssel, die mit der referenzierenden Spaltenliste im Fremdschlüssel übereinstimmen. .. – Luk

+0

Nun, in diesem Fall ist das Paar (Id, Application) ** nicht ** der Primärschlüssel in der Bibliothekentabelle.Sie können nur auf den Primärschlüssel in einer Elterntabelle verweisen - oder auf eine Spalte (oder einen Satz von Spalten)) Das ist Teil eines eindeutigen Indexes. Überprüfen Sie Ihre 'Bibliotheken' Tabelle! –

+0

Das war mein erster Gedanke auch, aber das SQL-Skript gibt 'CREATE TABLE [Bibliotheken] (' ... 'CONSTRAINT [PK_sf_Libraries] PRIMÄRSCHLÜSSEL ([Anwendung] ASC, [ID] ASC) WITH (PAD_INDEX = AUS, STATISTICS_NORECOMPUTE = AUS, IGNORE_DUP_KEY = AUS, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) EIN [PRIMARY] '... (Entschuldigung für dum ping all die SQL hier) – Luk

1

Die Content Tabelle wahrscheinlich mehrere doppelte Application Werte haben, die nicht auf Libraries abgebildet werden. Ist es möglich, die Application-Spalte aus dem Primärschlüssel-Index Libraries zu löschen und stattdessen als eindeutigen Schlüsselindex hinzuzufügen?

+0

Ja, vielleicht Duplikate für "Application", aber das ist nie erforderlich, um einzigartig zu sein. Das Paar '(LibraryID, Application)' kann sogar mehrere Werte haben - das ist nicht der PK in der 'Content'-Tabelle - es ist der PK in der' Libraries'-Tabelle! –

+0

OK, was passiert also, wenn Sie (LibraryID, Application) von Content haben, der nicht mit (ID, Application) in Bibliotheken übereinstimmt? Ab sofort gibt es keine Beschränkung, um dies zu erzwingen. Wenn OP nicht die aktuelle Struktur ändern möchte, würde ich ihm vorschlagen, versuchen, einen Unique Key-Index auf (LibraryID, Application) erstellen und sehen, ob es erfolgreich erstellt werden kann. Versuchen Sie erst dann, die Beziehung erneut zu erstellen. –

+0

Leider kann ich 'Libraries' überhaupt nicht anfassen. Die beiden Tabellen sollen sogar eine 1-1 Beziehung haben, weil ich keine neuen Spalten zu 'Bibliotheken' hinzufügen kann. Sie haben Recht, ein eindeutiger Index ist dort erforderlich (aber das hat das Problem nicht behoben) – Luk

0

Ich hatte das gleiche Problem und ich denke, ich habe die Lösung.

Wenn Ihr Feld Application in Tabelle Library einen Fremdschlüssel hat, die ein Feld in einer anderen Tabelle verweist (benannt Application ich würde wetten), dann ist dein Feld Application in Tabelle Library hat Application auch einen Fremdschlüssel zu Tisch.

Danach können Sie Ihren zusammengesetzten Fremdschlüssel tun.

Entschuldigung mein armes Englisch, und tut mir leid, wenn ich falsch liege.

7

Beachten Sie, dass die Felder in der gleichen Reihenfolge sein müssen. Wenn der Primärschlüssel, auf den Sie verweisen, als (Anwendung, ID) angegeben ist, muss Ihr Fremdschlüssel (Anwendung, ID) und NICHT (ID, Anwendung) verweisen, da sie als zwei verschiedene Schlüssel angesehen werden.

+0

Ich vermute das ist das Problem auch besonders.da er "Application" zuerst in seinem Primärschlüssel def ("PRIMARY KEY CLUSTERED ([Anwendung] ASC, [ID] ASC)" in seinem "Jul 5'10 um 15:07" auf die Accepted Answer ("marc_s's am "5. Juli 10 um 10:26") aber "ID" zuerst in beiden seiner Beispiele in seinem OP. Ich bin überrascht, dass niemand sonst (einschließlich der 500 (pinky-to-lips) TAUSAND mehr Repediert "marc_s") zeigte das in den 4 yrs 8 mos vor dir auf. – Tom

0

Der Schlüssel ist, "die Reihenfolge der Säule das gleiche sein sollte"

Beispiel:

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) 
) 

die Spaltenreihenfolge auf Tabelle A sollte ->A_ID dann A_Name; Das Definieren des Fremdschlüssels sollte ebenfalls in derselben Reihenfolge erfolgen.

Verwandte Themen