/ / nullで別のテーブルの値に対するチェック制約を作成する - sql、sql-server-2000、参照整合性

nulls-sql、sql-server-2000、参照整合性を持つ別のテーブルの値のチェック制約を作成する

AとBという2つのテーブルがあります。構造は次のようになります。

CREATE TABLE A (
w int NOT NULL,
x int NOT NULL,
y int NOT NULL,
CONSTRAINT PK_A PRIMARY KEY (w, x, y)
)

CREATE TABLE B (
w int NOT NULL,
y int NULL,
z int NOT NULL
)

テーブルBに入力された値のセットについて、wとyがテーブルAにあることを確認したい。テーブルBのy値がNULLの場合、wがテーブルAにあることだけを確認したい

サンプルデータ、挿入、および期待される結果

Table A
w  x  y
----------
1  1  1
1  1  2
1  2  1
1  3  2
2  1  1

INSERT INTO B (w, y, z) VALUES (1, 1, 3) -- good
INSERT INTO B (w, y, z) VALUES (1, NULL, 3) -- good
INSERT INTO B (w, y, z) VALUES (1, 1, 4) -- good
INSERT INTO B (w, y, z) VALUES (2, NULL, 3) -- good
INSERT INTO B (w, y, z) VALUES (1, 3, 1) -- fail
INSERT INTO B (w, y, z) VALUES (3, NULL, 1) -- fail

これが機能する方法はありますか? SQL Server 2000が使用されているのであれば、それを使用します。

回答:

回答№1は2

残念ながら、あなたはに外部キー制約を使用することはできません。 B.w そして B.y なぜならそれらは非ユニークなカラムを参照するからです。 A。しかし、あなたはトリガーを介してこのチェックを追加することができます:

create trigger check_w on B for insert, update
as
if not exists(select * from A join inserted on A.w = inserted.w)
begin
raiserror("W not in A!", 1, 1)
rollback transaction
end

GO

create trigger check_y on B for insert, update
as
if
(select y from inserted) is not null and
not exists(select * from A join inserted on A.y = inserted.y)
begin
raiserror("Y not null and not in A!", 1, 1)
rollback transaction
end

GO

あなたは間違いなく一つにこれら二つのトリガーを組み合わせることができます。

また、あなたにはAのトリガーが必要です。 delete 操作。 Bに一致する行がある場合、削除を防ぐか、カスケード削除操作を実行します。