由外键控制的值

时间:2013-06-02 19:48:44

标签: sql sql-server database foreign-keys

我在SQL Server中有一个非常简单的数据库,有这三个表:

  • TheaterID, is3D,其他值...)
  • ShowID, Theater_ID, Movie_ID, date, time,其他值...)
  • MovieID, is3D,其他值...)

我想确保 3D电影只能在3D影院上映。仅在2D影院中的2D电影,并且仅通过外键(无触发器等)进行。

1 个答案:

答案 0 :(得分:3)

要仅通过外键执行此操作,您还需要向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上的交叉联接会将其相乘,从而导致违反唯一约束并阻止此情况。