Aggiungi relazione Chiave esterna tra due database

Ho due tabelle in due database diversi. In table1 (è in database1) c’è una colonna chiamata column1 ed è una chiave primaria. Ora nella tabella 2 (è in databse2) c’è una colonna chiamata coulmn2 e voglio aggiungerla come chiave esterna.

Ho provato ad aggiungerlo e mi ha dato il seguente errore:

Messaggio 1763, livello 16, stato 0, riga 1
I riferimenti alle chiavi esterne tra database non sono supportati. Chiave esterna Database2.table2.

Messaggio 1750, livello 16, stato 0, riga 1
Imansible creare un vincolo. Vedi errori precedenti.

Come faccio a farlo Dal momento che le tabelle sono in diversi database.

Dovresti gestire il vincolo referenziale tra i database utilizzando un trigger.


Fondamentalmente si crea un inserto, si aggiorna il trigger per verificare l’esistenza della Chiave nella tabella della chiave primaria. Se la chiave non esiste, ripristinare l’inserimento o l’aggiornamento e quindi gestire l’eccezione.

Esempio:

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 

Modificato: giusto per chiarire Questo non è l’approccio migliore per rafforzare l’integrità referenziale. Idealmente vorrai entrambe le tabelle nello stesso db ma se questo non è ansible. Quindi quanto sopra è un potenziale lavoro per te.

Se è necessaria un’integrità solida, avere entrambe le tabelle in un unico database e utilizzare un vincolo FK. Se la tua tabella genitore si trova in un altro database, nulla impedisce a nessuno di ripristinare quel database genitore da un vecchio backup, e quindi hai degli orfani.

Questo è il motivo per cui FK tra i database non è supportato.

Secondo la mia esperienza, il modo migliore per gestirli quando la principale fonte di informazioni autorevole per due tabelle correlate deve essere in due database separati è sincronizzare una copia della tabella dalla posizione primaria alla posizione secondaria (usando T- SQL o SSIS con controllo degli errori appropriato: non è ansible troncare e ripopolare una tabella quando ha un riferimento a una chiave esterna, quindi ci sono alcuni modi per rendere l’aggiornamento del gatto sull’aggiornamento della tabella).

Quindi aggiungere una relazione FK tradizionale nella seconda posizione alla tabella che è effettivamente una copia di sola lettura.

È ansible utilizzare un trigger o un processo pianificato nella posizione principale per mantenere aggiornata la copia.

È ansible utilizzare il vincolo di controllo con una funzione definita dall’utente per effettuare il controllo. È più affidabile di un trigger. Può essere disabilitato e ritriggersto quando necessario come chiavi esterne e ricontrollato dopo un ripristino del database2.

 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) 

La risposta breve è che SQL Server (a partire da SQL 2008) non supporta chiavi esterne del database incrociato, come indica il messaggio di errore.

Sebbene non sia ansible avere l’integrità referenziale dichiarativa (FK), è ansible raggiungere lo stesso objective utilizzando i trigger. È un po ‘meno affidabile, perché la logica che scrivi può avere bug, ma ti porterà lì ugualmente.

Vedere i documenti SQL @ http://msdn.microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx Quale stato:

I trigger sono spesso utilizzati per far rispettare le regole aziendali e l’integrità dei dati. SQL Server fornisce l’integrità referenziale dichiarativa (DRI) attraverso le istruzioni di creazione della tabella (ALTER TABLE e CREATE TABLE); tuttavia, il DRI non fornisce l’integrità referenziale tra database. Per applicare l’integrità referenziale (regole sulle relazioni tra le chiavi primarie e quelle esterne delle tabelle), utilizzare i vincoli di chiave primaria e esterna (le parole chiave PRIMARY KEY e FOREIGN KEY di ALTER TABLE e CREATE TABLE). Se esistono dei vincoli sulla tabella del trigger, questi vengono controllati dopo l’esecuzione del trigger INSTEAD OF e prima dell’esecuzione del trigger AFTER. Se i vincoli vengono violati, le azioni trigger di INSTEAD OF vengono ripristinate e il trigger AFTER non viene eseguito (triggersto).

C’è anche una discussione OK su SQLTeam – http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=31135

Come dice il messaggio di errore, questo non è supportato su SQL Server. L’unico modo per garantire l’integrità refrerenziale è lavorare con i trigger.