Добавление связи внешнего ключа между двумя базами данных
У меня есть две таблицы в двух разных базах данных. В таблице 1 (она находится в database1) есть столбец, называемый column1, и это первичный ключ. Теперь в таблице 2 (она находится в databse2) есть столбец coulmn2, и я хочу добавить его в качестве внешнего ключа.
Я попытался добавить его, и это дало мне следующую ошибку:
Msg 1763, Уровень 16, Состояние 0, Строка 1
Ссылки на внешние ключи между базами данных не поддерживаются. Внешний ключ база данных 2.таблица2.Msg 1750, Уровень 16, Состояние 0, Строка 1
Не удалось создать ограничение. См. предыдущие ошибки.
Как это сделать, так как таблицы находятся в разных базах данных.
6 ответов:
вам нужно будет управлять ссылочным ограничением между базами данных с помощью триггера.
в основном вы создаете триггер insert, update для проверки существования ключа в таблице первичных ключей. Если ключ не существует, то верните вставку или обновление, а затем обработайте исключение.
пример:
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
редактировать: просто для уточнения. Это не лучший подход с обеспечением ссылочной целостности. В идеале вы хотите, чтобы обе таблицы находились в одной БД, но если это невозможно. Тогда вышеизложенное является потенциальной работой для вас.
Если вам нужна целостность rock solid, имейте обе таблицы в одной базе данных и используйте ограничение FK. Если ваша родительская таблица находится в другой базе данных, ничто не мешает восстановить эту родительскую базу данных из старой резервной копии, а затем у вас есть сироты.
вот почему FK между базами данных не поддерживается.
затем добавить традиционное отношение FK во втором месте к таблице, которая фактически является копией только для чтения.
для обновления копии можно использовать триггер или запланированное задание в основном расположении.
вы можете использовать ограничение check с помощью пользовательской функции, чтобы проверить. Это более надежно, чем триггер. Он может быть отключен и повторно включен при необходимости так же, как внешние ключи и перепроверен после восстановления 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)
короткий ответ заключается в том, что SQL Server (начиная с SQL 2008) не поддерживает внешние ключи кросс-базы данных-как указано в сообщении об ошибке.
хотя вы не можете иметь декларативную ссылочную целостность (FK), вы можете достичь той же цели с помощью триггеров. Это немного менее надежно, потому что логика, которую вы пишете, может иметь ошибки, но она все равно приведет вас туда.
см. SQL docs @ http://msdn.microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx В каком состоянии:
триггеры часто используются для реализации бизнес-правила и целостность данных. язык SQL Сервер предоставляет декларативный ссылочная целостность (DRI) до конца инструкции по созданию таблицы (ALTER Таблица и создать таблицу); однако, DRI не предоставляет кросс-базу данных ссылочная целостность. Принуждать ссылочная целостность (правила о отношения между первичным и внешние ключи таблиц), использовать первичные и ограничения внешнего ключа (в Первичный ключ и внешний ключ ключевые слова изменить таблицу и создать таблицу). Если ограничения существуют на триггере таблица, они проверяются после Вместо выполнения триггера и предшествующего после выполнения триггера. Если ограничения нарушаются, вместо этого Триггерных действий откатываются и триггер AFTER не выполняется (обожженный.)
существует также ОК обсуждение на SQLTeam - http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=31135