Добавить отношение внешнего ключа между двумя базами данных

У меня есть две таблицы в двух разных базах данных. В таблице 1 (в базе данных 1) есть столбец с именем column1, и это первичный ключ. Теперь в таблице 2 (в базе данных 2) есть столбец с именем column2, и я хочу добавить его в качестве внешнего ключа.

Я попытался добавить его, и он дал мне следующую ошибку:

Сообщение 1763, Уровень 16, Состояние 0, Строка 1
Ссылки на внешние ключи между базами данных не поддерживаются. Внешний ключ Database2.table2.

Сообщение 1750, уровень 16, состояние 0, строка 1
Не удалось создать ограничение. Смотрите предыдущие ошибки.

Как мне это сделать, так как таблицы находятся в разных базах данных.

Ответ 1

Вам нужно будет управлять ссылочным ограничением между базами данных с помощью триггера.


В основном вы создаете вставку, триггер обновления, чтобы проверить наличие ключа в таблице основных ключей. Если ключ не существует, верните вставку или обновление и обработайте исключение.

Пример:

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

Отредактировано: Просто уточнить. Это не лучший подход к обеспечению ссылочной целостности. В идеале вы хотели бы, чтобы обе таблицы находились в одном и том же db, но если это невозможно. Тогда вышесказанное - потенциальная работа для вас.

Ответ 2

Если вам нужна надежная целостность, используйте обе таблицы в одной базе данных и используйте ограничение FK. Если ваша родительская таблица находится в другой базе данных, ничто не мешает кому-либо восстановить эту родительскую базу данных из старой резервной копии, а затем у вас есть сироты.

Вот почему FK между базами данных не поддерживается.

Ответ 3

По моему опыту, лучший способ справиться с этим, когда первичный авторитетный источник информации для двух таблиц, которые связаны между собой, должен быть в двух отдельных базах данных - это синхронизация копии таблицы из первичного местоположения во вторичное местоположение ( используя T-SQL или SSIS с соответствующей проверкой ошибок - вы не можете усекать и повторно заполнять таблицу, пока она имеет ссылку на внешний ключ, поэтому есть несколько способов скинуть кошку на обновление таблицы).

Затем добавьте традиционное отношение FK во втором местоположении к таблице, которое фактически является копией только для чтения.

Вы можете использовать триггер или запланированное задание в основном месте, чтобы обновить копию.

Ответ 4

Вы можете использовать проверочное ограничение с помощью определенной пользователем функции для проверки. Он более надежный, чем триггер. Он может быть отключен и повторно подключен, если необходимо, так же, как и внешние ключи, и перепроверяется после восстановления базы данных.

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)

Ответ 5

Короткий ответ заключается в том, что SQL Server (с SQL 2008) не поддерживает внешние ключи кросс-базы данных, как указано в сообщении об ошибке.

Пока вы не можете иметь декларативную ссылочную целостность (FK), вы можете достичь той же цели, используя триггеры. Это немного менее надежно, потому что логика, которую вы пишете, может иметь ошибки, но она заставит вас там точно так же.

См. SQL docs @http://msdn.microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx В каком состоянии:

Триггеры часто используются для обеспечения соблюдения бизнес-правил и целостности данных. SQL Сервер предоставляет декларативные ссылочной целостности (DRI) через инструкции создания таблицы (ALTER ТАБЛИЦА и СОЗДАТЬ ТАБЛИЦУ); однако, DRI не предоставляет кросс-базу данных ссылочная целостность. Для обеспечения ссылочной целостности (правила о отношения между внешние ключи таблиц), используйте первичные и ограничения внешнего ключа ( Ключевые слова PRIMARY KEY и FOREIGN KEY из ALTER TABLE и CREATE TABLE). Если существуют ограничения на триггер таблицы, они проверяются после INSTEAD запуска триггера и предыдущих к выполнению триггера AFTER. Если ограничения нарушаются, INSTEAD Действия триггера откатятся назад и триггер AFTER не выполняется (Уволен).

В SQLTeam также обсуждается ОК - http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=31135

Ответ 6

Как говорится в сообщении об ошибке, это не поддерживается на сервере sql. Единственный способ гарантировать корректность целостности - это работать с триггерами.