在检查约束中使用查询

Using queries in check constraints

我试图对一行使用检查约束,而我只有私钥。我不知道是否有其他方法可以检查此类内容,我是 SQL 的新手,所以我也乐于接受建议。

这是一个最小的例子:

我有以下表格:

Buildings:
building_id: int GENERATED PRIMARY KEY

Floors:
floor_id: int GENERATED PRIMARY KEY
floor_nr: int
building_id: int FOREIGN KEY REFERENCES Buildings (building_id)

Glasses:
glass_id: int GENERATED PRIMARY KEY
building_id: int FOREIGN KEY REFERENCES Buildings (building_id)

Floors_Glasses:
floor_id: int FOREIGN KEY REFERENCES Floors (floor_id)
glass_id: int FOREIGN KEY REFERENCES Glasses (building_id)

当我想把玻璃杯移到地板上时,我需要检查是否

(SELECT building_id FROM Floors WHERE floor_id = floor.floor_id) == glass.building_id

所以我不必为我编写的每个查询重复上面的查询。

编辑:

我最终使用约束触发器如下:

CREATE CONSTRAINT TRIGGER "trigger name"
    AFTER UPDATE OF "column name" ON "table name"
    FOR EACH ROW EXECUTE PROCEDURE "procedure name"

并引发异常

raise exception 'message' using errcode = 'restrict_violation';

如果一个玻璃真的可以同时在多个楼层,将 building_id 添加到 floors_glasses 并创建从 table 到 floors 的复合外键和glasses 包括 building_id 列。这将保证您的完整性约束。

您不能定义引用其他行或 table 的检查约束,因为一旦您修改这些其他对象,它就会失效。例如,恢复转储可能会失败。

您始终可以在应用级别强制执行此规则。但是,我总是不信任这些应用程序(因为它们总是充满错误),所以我个人更喜欢尽可能在数据库级别执行规则。

它需要更多的启动工作,但可以在以后为您节省大量时间,因为它从一开始就防止了数据损坏问题。

你可以这样做:

create table buildings (
  building_id int primary key not null
);

create table floors (
  building_id int not null references buildings (building_id),
  floor_id int not null,
  floor_nr int,
  primary key (building_id, floor_id)
);

create table glasses (
  building_id int not null references buildings (building_id),
  glass_id int not null,
  glass_price int,
  primary key (building_id, glass_id)
);

create table floor_glasses (
  building_id int not null,
  floor_id int not null,
  glass_id int not null,
  primary key (building_id, floor_id, glass_id),
  foreign key (building_id, floor_id) references floors (building_id, floor_id),
  foreign key (building_id, glass_id) references glasses (building_id, glass_id)
);

关键概念在最后table。在 two 外键引用中只使用了 onebuilding_id。此 引用共享 可确保最后 table 中引用的楼层和玻璃始终属于同一建筑物。