web-dev-qa-db-ja.com

2つのデータベース間に外部キー関係を追加する

2つの異なるデータベースに2つのテーブルがあります。 table1(database1)にはcolumn1と呼ばれる列があり、それは主キーです。さて、table2(database2)にはcolumn2という列があり、それを外部キーとして追加したいと思います。

追加しようとすると、次のエラーが表示されました。

メッセージ1763、レベル16、状態0、行1
クロスデータベース外部キー参照はサポートされていません。外部キーDatabase2.table2。

メッセージ1750、レベル16、状態0、行1
制約を作成できませんでした。以前のエラーを参照してください。

テーブルは異なるデータベースにあるため、どうすればよいですか。

69
Sam

トリガーを使用して、データベース全体の参照制約を管理する必要があります。


基本的に、挿入、更新トリガーを作成して、主キーテーブル内のキーの存在を確認します。キーが存在しない場合、挿入または更新を元に戻し、例外を処理します。

例:

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

編集済み:明確にするため。これは、参照整合性を強制する最善の方法ではありません。理想的には、同じデータベースに両方のテーブルが必要ですが、それが不可能な場合。その後、上記は潜在的な回避策です。

69
John Hartsock

堅実な整合性が必要な場合は、1つのデータベースに両方のテーブルを用意し、FK制約を使用します。親テーブルが別のデータベースにある場合、古いバックアップからその親データベースを復元することを誰も妨げることはありません。

これが、データベース間のFKがサポートされていない理由です。

38
A-K

私の経験では、関連する2つのテーブルの主要な信頼できる情報源が2つの別々のデータベースにある必要がある場合にこれを処理する最良の方法は、テーブルのコピーをプライマリロケーションからセカンダリロケーションに同期することです(T-適切なエラーチェックを備えたSQLまたはSSIS-外部キー参照がある間はテーブルを切り詰めたり再入力したりできないため、テーブルの更新時に猫のスキンを作成する方法がいくつかあります)。

次に、2番目の場所にある従来のFK関係を、事実上読み取り専用コピーであるテーブルに追加します。

プライマリロケーションでトリガーまたはスケジュールされたジョブを使用して、コピーを最新の状態に保つことができます。

24
Cade Roux

ユーザー定義関数でチェック制約を使用してチェックを行うことができます。トリガーよりも信頼性があります。外部キーと同じように、必要に応じて無効化および再有効化でき、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)
17
Camilo J

簡単な答えは、SQL Server(SQL 2008以降)は、クロスデータベース外部キーをサポートしていないことです(エラーメッセージが示すとおり)。

宣言的な参照整合性(FK)を持つことはできませんが、トリガーを使用して同じ目標を達成できます。あなたが書くロジックにはバグがあるかもしれないので、それは少し信頼性が低いですが、それはあなたを同じようにそこに導きます。

SQLドキュメントを参照してください@ http://msdn.Microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx どの状態:

トリガーは、ビジネスルールとデータの整合性を強化するためによく使用されます。 SQL Serverは、テーブル作成ステートメント(ALTER TABLEおよびCREATE TABLE)を通じて宣言参照整合性(DRI)を提供します。ただし、DRIはデータベース間の参照整合性を提供しません。参照整合性(テーブルの主キーと外部キーの関係に関する規則)を強制するには、主キーと外部キーの制約(ALTER TABLEおよびCREATE TABLEのPRIMARY KEYおよびFOREIGN KEYキーワード)を使用します。トリガーテーブルに制約が存在する場合、INSTEAD OFトリガーの実行後、AFTERトリガーの実行前に制約がチェックされます。制約に違反すると、INSTEAD OFトリガーアクションはロールバックされ、AFTERトリガーは実行されません(起動されます)。

SQLTeamでの議論もあります- http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=31135

3
EBarr

エラーメッセージにあるように、これはSQLサーバーではサポートされていません。参照整合性を確保する唯一の方法は、トリガーを使用することです。

0
Jan