89

SQL Server 2008 で与えられた

TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)

列が にある値に制限されるTableZ(A_or_B_ID, Z_Data)ように定義することは可能ですか? ビューに対する外部キーでこれを行うことはできますか?Z.A_or_B_IDViewC

4

7 に答える 7

118

外部キーでビューを参照することはできません。

于 2009-01-15T15:25:06.597 に答える
31

古いSQLServerエディションでは、外部キーはトリガーを介してのみ可能でした。挿入された値が関連するテーブルの1つにも表示されるかどうかをチェックする挿入トリガーを作成することにより、カスタム外部キーを模倣できます。

于 2013-03-10T08:59:26.590 に答える
19

本当にA_or_B_IDTableZ が必要な場合は、2 つの同様のオプションがあります。

1)テーブル z に null 許容列をA_ID追加し、これら 2 つの列で ISNULL を使用して計算列を作成し、またはの一方のみが null でないような CHECK 制約を追加します。B_IDA_or_B_IDA_IDB_ID

2) TableName 列をテーブル z に追加し、A または B のいずれかを含むように制約します。適切なテーブルが (CASE 式を使用して) 指定された場合にのみ非 null になる計算列としてA_IDおよびを作成します。B_IDそれらも永続化する

どちらの場合も、ベース テーブルへの適切な外部キーを持つことができる列がA_IDあります。B_ID違いは、どの列が計算されるかです。A_or_B_ID また、2 つの ID 列のドメインが重複しない場合は、上記のオプション 2 で TableName は必要ありません - case 式がどのドメインに該当するかを判断できる限り

(フォーマットを修正してくれたコメントに感謝します)

于 2009-01-15T15:36:45.530 に答える
8

申し訳ありませんが、SQL Server のビューに FK することはできません。

于 2009-01-15T15:25:17.003 に答える
5

別のオプションがあります。TableATableB呼ばれる新しいテーブルのサブクラスとして扱いますTablePrimeTableBのID値が一致しないように、のID値を調整しTableAます。TablePrimePKにIDを作成し、すべてのTableA'およびTableB'(調整済み)IDをに挿入しTablePrimeます。の同じIDに対して、 PKTableATableBFK関係を作成しTablePrimeます。

これでスーパータイプ/サブタイプパターンが作成され、 ( -A-または-BのいずれかTablePrimeが必要な場合)または個々のテーブルの1つ(AのみまたはBのみが必要な場合)に制約を加えることができます。

詳細が必要な場合は、お問い合わせください。AとBが相互に排他的であることを確認できるバリエーションがあります。または、作業しているものが両方同時に存在する可能性があります。可能であれば、FKでそれを形式化するのが最善です。

于 2012-07-27T20:34:36.503 に答える
2

チェックを行うユーザー定義関数 fCheckIfValueExists(columnValue) を参照する制約を追加する方が簡単です。これは、値が存在する場合は true を返し、存在しない場合は false を返します。

利点は、複数の列を受け取り、それらを使用して計算を実行し、null を受け入れ、主キーに正確に対応しない値を受け入れたり、結合の結果と比較したりできることです。

欠点は、オプティマイザがすべての外部キー トリックを使用できないことです。

于 2015-12-29T17:56:50.237 に答える
1

申し訳ありませんが、厳密な意味では、ビューに外部キーを設定することはできません。理由は次のとおりです。

InnoDB は、外部キーを備えた唯一の MySQL 用組み込みストレージ エンジンです。InnoDB テーブルは、engine = 'InnoDB' で information_schema.tables に登録されます。

ビューは、information_schema.tables に登録されていますが、NULL ストレージ エンジンを持っています。MySQL には、未定義のストレージ エンジンを持つテーブルに外部キーを持つメカニズムはありません。

ありがとう!

于 2018-08-13T02:15:18.983 に答える