12

テーブル内の 2 つの null 許容 FK の間に制約を定義したいと思います。一方が null の場合、もう一方は値を必要としますが、両方を null にすることはできず、両方を値を持つこともできません。ロジックは、派生テーブルがいずれかの FK テーブルからデータを継承して、その型を決定します。また、楽しいボーナスポイントを得るために、これは悪い考えですか?

4

3 に答える 3

19

それを達成する1つの方法は、「排他的OR」が実際に何を意味するかを簡単に書き留めることです:

CHECK (
    (FK1 IS NOT NULL AND FK2 IS NULL)
    OR (FK1 IS NULL AND FK2 IS NOT NULL)
)

ただし、多くの FK がある場合、上記の方法はすぐに扱いにくくなる可能性があります。その場合、次のようにすることができます。

CHECK (
    1 = (
        (CASE WHEN FK1 IS NULL THEN 0 ELSE 1 END)
        + (CASE WHEN FK2 IS NULL THEN 0 ELSE 1 END)
        + (CASE WHEN FK3 IS NULL THEN 0 ELSE 1 END)
        + (CASE WHEN FK4 IS NULL THEN 0 ELSE 1 END)
        ...
    )
)

ところで、そのパターンには正当な用途があります。たとえば、これは (ただし、遅延制約がないため、MS SQL Server には適用できません)。あなたの特定のケースでそれが正当であるかどうかは、あなたがこれまでに提供した情報に基づいて判断することはできません.

于 2012-06-20T20:34:58.850 に答える
1

チェック制約を使用できます:

create table #t (
   a int,
   b int);

alter table #t add constraint c1 
check ( coalesce(a, b) is not null and a*b is null );

insert into #t values ( 1,null);

insert into #t values ( null ,null);

ランニング:

The INSERT statement conflicted with the CHECK constraint "c1". 
于 2012-06-20T20:15:02.887 に答える
-1

別の方法は、プロシージャでこのチェック制約を定義することです。派生テーブルにレコードを挿入する前に、制約が満たされている必要があります。それ以外の場合、挿入は失敗するか、エラーを返します。

于 2012-06-20T20:26:30.293 に答える