webentwicklung-frage-antwort-db.com.de

Hinzufügen einer Fremdschlüsselbeziehung zwischen zwei Datenbanken

Ich habe zwei Tabellen in zwei verschiedenen Datenbanken. In Tabelle1 (in Datenbank1) gibt es eine Spalte namens Spalte1 und es ist ein Primärschlüssel. Jetzt gibt es in Tabelle2 (in Datenbank2) eine Spalte mit dem Namen Spalte2 und ich möchte sie als Fremdschlüssel hinzufügen.

Ich habe versucht, es hinzuzufügen und es gab mir den folgenden Fehler:

Meldung 1763, Ebene 16, Status 0, Zeile 1
Datenbankübergreifende Fremdschlüsselreferenzen werden nicht unterstützt. Fremdschlüssel Database2.table2.

Meldung 1750, Ebene 16, Status 0, Zeile 1
Einschränkung konnte nicht erstellt werden. Siehe vorherige Fehler.

Wie mache ich das, da die Tabellen in verschiedenen Datenbanken sind.

69
Sam

Sie müssten die referenzielle Einschränkung mithilfe eines Triggers datenbankübergreifend verwalten.


Grundsätzlich erstellen Sie einen Einfüge-/Aktualisierungs-Trigger, um das Vorhandensein des Schlüssels in der Primärschlüsseltabelle zu überprüfen. Wenn der Schlüssel nicht vorhanden ist, setzen Sie die Einfügung oder Aktualisierung zurück und behandeln Sie dann die Ausnahme.

Beispiel:

Create Trigger dbo.MyTableTrigger ON dbo.MyTable, After Insert, Update
As
Begin

   If NOT Exists(select PK from OtherDB.dbo.TableName where PK in (Select FK from inserted) BEGIN
      -- Handle the Referential Error Here
   END

END

Bearbeitet: Nur zur Verdeutlichung. Dies ist nicht der beste Ansatz zur Durchsetzung der referenziellen Integrität. Idealerweise möchten Sie beide Tabellen in derselben Datenbank haben, aber wenn dies nicht möglich ist. Dann ist das Obige eine mögliche Lösung für Sie.

69
John Hartsock

Wenn Sie eine solide Integrität benötigen, müssen Sie beide Tabellen in einer Datenbank haben und eine FK-Einschränkung verwenden. Befindet sich Ihre übergeordnete Tabelle in einer anderen Datenbank, hindert nichts daran, diese übergeordnete Datenbank aus einer alten Sicherung wiederherzustellen, und dann haben Sie verwaiste Daten.

Aus diesem Grund wird FK zwischen Datenbanken nicht unterstützt.

38
A-K

Nach meiner Erfahrung besteht die beste Möglichkeit, dies zu handhaben, wenn die primäre maßgebliche Informationsquelle für zwei Tabellen, die in Beziehung stehen, in zwei separaten Datenbanken sein muss, darin, eine Kopie der Tabelle vom primären zum sekundären Speicherort zu synchronisieren (mithilfe von T- SQL oder SSIS mit entsprechender Fehlerprüfung - Sie können eine Tabelle nicht abschneiden und erneut auffüllen, solange sie über einen Fremdschlüsselverweis verfügt.

Fügen Sie dann eine traditionelle FK-Beziehung an der zweiten Stelle zur Tabelle hinzu, die praktisch eine schreibgeschützte Kopie ist.

Sie können einen Auslöser oder einen geplanten Auftrag am primären Speicherort verwenden, um die Kopie auf dem neuesten Stand zu halten.

24
Cade Roux

Sie können die Prüfbedingung mit einer benutzerdefinierten Funktion verwenden, um die Prüfung durchzuführen. Es ist zuverlässiger als ein Auslöser. Sie kann wie Fremdschlüssel bei Bedarf deaktiviert und wieder aktiviert und nach einer Datenbankwiederherstellung erneut überprüft werden.

CREATE FUNCTION dbo.fn_db2_schema2_tb_A
(@column1 INT) 
RETURNS BIT
AS
BEGIN
    DECLARE @exists bit = 0
    IF EXISTS (
      SELECT TOP 1 1 FROM DB2.SCHEMA2.tb_A 
      WHERE COLUMN_KEY_1 =  @COLUMN1
    ) BEGIN 
         SET @exists = 1 
      END;
      RETURN @exists
END
GO

ALTER TABLE db1.schema1.tb_S
  ADD CONSTRAINT CHK_S_key_col1_in_db2_schema2_tb_A
    CHECK(dbo.fn_db2_schema2_tb_A(key_col1) = 1)
17
Camilo J

Die kurze Antwort lautet, dass SQL Server (ab SQL 2008) keine datenbankübergreifenden Fremdschlüssel unterstützt - wie in der Fehlermeldung angegeben.

Während Sie keine deklarative referenzielle Integrität (FK) haben können, können Sie dasselbe Ziel mit Triggern erreichen. Es ist etwas weniger zuverlässig, da die von Ihnen geschriebene Logik möglicherweise Fehler enthält, Sie aber trotzdem dorthin bringt.

Siehe die SQL-Dokumente @ http://msdn.Microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx Welcher Status:

Trigger werden häufig zur Durchsetzung von Geschäftsregeln und Datenintegrität verwendet. SQL Server bietet deklarative referenzielle Integrität (DRI) über die Anweisungen zur Tabellenerstellung (ALTER TABLE und CREATE TABLE). DRI bietet jedoch keine datenbankübergreifende referenzielle Integrität. Verwenden Sie zum Erzwingen der referenziellen Integrität (Regeln für die Beziehungen zwischen Primär- und Fremdschlüsseln von Tabellen) Primär- und Fremdschlüsseleinschränkungen (die Schlüsselwörter PRIMARY KEY und FOREIGN KEY von ALTER TABLE und CREATE TABLE). Wenn Einschränkungen in der Triggertabelle vorhanden sind, werden diese nach der Ausführung des INSTEAD OF-Triggers und vor der Ausführung des AFTER-Triggers überprüft. Wenn die Einschränkungen verletzt werden, werden die INSTEAD OF-Triggeraktionen zurückgesetzt und der AFTER-Trigger wird nicht ausgeführt (ausgelöst).

Es gibt auch eine OK-Diskussion bei SQLTeam - http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=31135

3
EBarr

Wie die Fehlermeldung besagt, wird dies auf SQL Server nicht unterstützt. Die einzige Möglichkeit, die Integrität der Referenz zu gewährleisten, besteht darin, mit Triggern zu arbeiten.

0
Jan