2010-12-15 15 views
40

Ich habe zwei Tabellen in zwei verschiedenen Datenbanken. In Tabelle 1 (Es ist in Datenbank1) gibt es eine Spalte namens Spalte1 und es ist ein Primärschlüssel. Jetzt in Tabelle 2 (Es ist in Datenbank2) gibt es eine Spalte namens coulmn2 und ich möchte es als Fremdschlüssel hinzufügen.Fremdschlüssel Beziehung zwischen zwei Datenbanken hinzufügen

Ich habe versucht, es zu addieren und es gab mir die folgende Fehlermeldung:

Msg 1763, Level 16, State 0, Line 1
Cross-database foreign key references are not supported. Foreign key Database2.table2.

Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.

Wie kann ich tun, dass, da die Tabellen in unterschiedlichen Datenbanken.

Antwort

40

Sie müssten die referenzielle Einschränkung über Datenbanken mithilfe eines Triggers verwalten.

Grundsätzlich erstellen Sie eine Einfügung, aktualisieren Sie 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 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 

Editiert: Nur um zu klären. Dies ist nicht der beste Ansatz, um die referenzielle Integrität zu erzwingen. Idealerweise würden Sie beide Tabellen in der gleichen db aber wenn das nicht möglich ist. Dann ist das oben genannte eine mögliche Arbeit für Sie.

+0

Können Sie mich mit einem Beispiel erklären – Sam

+0

Ähnlich muss ich Update Trigger auch erstellen. – Sam

+0

@Sam Ja ... aber Sie können einen Trigger sowohl für Einfügen als auch für Update erstellen. Siehe meine bearbeitete Antwort –

0

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

+0

Können Sie mir ein Beispiel erklären – Sam

3

Die kurze Antwort ist, dass SQL Server (ab SQL 2008) keine Cross-Datenbank-Fremdschlüssel unterstützt - wie die Fehlermeldung angibt.

Während Sie keine deklarative referentielle Integrität (FK) haben können, können Sie dasselbe Ziel mithilfe von Triggern erreichen. Es ist ein bisschen weniger zuverlässig, weil die Logik, die Sie schreiben, Fehler haben kann, aber es wird Sie dort genauso bringen.

Siehe die SQL-docs @http://msdn.microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx Welche Zustand:

Triggers are often used for enforcing business rules and data integrity. SQL Server provides declarative referential integrity (DRI) through the table creation statements (ALTER TABLE and CREATE TABLE); however, DRI does not provide cross-database referential integrity. To enforce referential integrity (rules about the relationships between the primary and foreign keys of tables), use primary and foreign key constraints (the PRIMARY KEY and FOREIGN KEY keywords of ALTER TABLE and CREATE TABLE). If constraints exist on the trigger table, they are checked after the INSTEAD OF trigger execution and prior to the AFTER trigger execution. If the constraints are violated, the INSTEAD OF trigger actions are rolled back and the AFTER trigger is not executed (fired).

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

22

Wenn Sie feste Integrität rocken, haben beide Tabellen in einer Datenbank und Verwenden Sie eine FK-Bedingung. Wenn sich Ihre Elterntabelle in einer anderen Datenbank befindet, verhindert nichts, dass jemand diese übergeordnete Datenbank von einer alten Sicherung wiederherstellt, und dann haben Sie Waisen.

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

20

Nach meiner Erfahrung ist der beste Weg, dies zu behandeln, wenn die primäre autorisierende Quelle von Informationen für zwei Tabellen, die verwandt sind, in zwei separaten Datenbanken sein muss, eine Kopie der Tabelle vom primären Speicherort zum sekundären Speicherort zu synchronisieren (Verwenden von T-SQL oder SSIS mit entsprechender Fehlerprüfung - Sie können eine Tabelle nicht abschneiden und neu auffüllen, während sie einen Fremdschlüsselverweis hat. Es gibt also einige Möglichkeiten, die Katze bei der Tabellenaktualisierung zu häuten.)

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

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

+0

Re. "Sie können einen Job am primären Speicherort auslösen oder planen, um die Kopie auf dem neuesten Stand zu halten": Warum verwenden Sie nicht einfach die SQL Server-Replikation (speziell den Transaktions-/Zusammenführungs-Typ seit der Kopie des Abonnenten (die Kopie, die die Tabellen mit Fremdschlüssel-Constraints benötigt) muss schreibgeschützt sein) Siehe: [link] (https://docs.microsoft.com/en-us/sql/relational-databases/replication/sql-server-replication) – Tom

+0

@Tom ja, Sie können sicherlich Replikation verwenden, um eine Kopie der zu behalten Tabelle in einer entfernten Datenbank aktualisiert. –

11

Sie könnten die Prüfbedingung mit einer benutzerdefinierten Funktion verwenden, um die Prüfung durchzuführen. Es ist zuverlässiger als ein Auslöser. Sie kann bei Bedarf wie bei Fremdschlüsseln deaktiviert und erneut aktiviert werden 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) 
Verwandte Themen