SQL Server に非常に単純なデータベースがあり、次の 3 つのテーブルがあります。
Theater
(ID, is3D,
他の値...)Show
(ID, Theater_ID, Movie_ID, date, time,
他の値...)Movie
(ID, is3D,
他の値...)
3D 映画は 3D シアターでのみ再生できるようにしたいと思います。2D 映画は 2D シアターでのみ、外部キーのみで実行します (トリガーなどはありません)。
SQL Server に非常に単純なデータベースがあり、次の 3 つのテーブルがあります。
Theater
(ID, is3D,
他の値...)Show
(ID, Theater_ID, Movie_ID, date, time,
他の値...)Movie
(ID, is3D,
他の値...)3D 映画は 3D シアターでのみ再生できるようにしたいと思います。2D 映画は 2D シアターでのみ、外部キーのみで実行します (トリガーなどはありません)。
外部キーだけでこれを行うには、is3D
列を追加し、論理的に冗長な制約Show
をいくつか追加する必要があります。UNIQUE
CREATE TABLE Theater
(
ID INT PRIMARY KEY,
is3D BIT NOT NULL,
/*Other columns*/
UNIQUE(ID, is3D)
)
CREATE TABLE Movie
(
ID INT PRIMARY KEY,
is3D BIT NOT NULL,
/*Other columns*/
UNIQUE(ID, is3D)
)
CREATE TABLE Show
(
ID INT PRIMARY KEY,
Theater_ID INT NOT NULL,
Movie_ID INT NOT NULL,
is3D BIT NOT NULL,
/*Other columns*/
FOREIGN KEY(Theater_ID, is3D) REFERENCES Theater (ID, is3D),
FOREIGN KEY(Movie_ID, is3D) REFERENCES Movie (ID, is3D)
)
以下のように、追加の列や一意の制約を必要とせずに、インデックス付きビューを使用してこれを宣言的に適用することもできます。
CREATE TABLE dbo.TwoRows
(
X INT PRIMARY KEY
);
INSERT INTO dbo.TwoRows
VALUES (1), (2)
GO
CREATE VIEW V
WITH SCHEMABINDING
AS
SELECT S.Theater_ID,
S.Movie_ID
FROM dbo.Show S
JOIN dbo.Theater T
ON S.Theater_ID = T.ID
JOIN dbo.Movie M
ON S.Movie_ID = M.ID
CROSS JOIN dbo.TwoRows
WHERE T.is3D <> M.is3D
GO
CREATE UNIQUE CLUSTERED INDEX IX
ON V(Theater_ID, Movie_ID)
ルールが満たされている場合、基礎となるクエリは常に行を返さないようにする必要があります。いずれかの行が返された場合、クロス結合dbo.TwoRows
によって乗算され、一意の制約違反が発生し、状況が防止されます。