基于 FK 关系的约束
Constraint based on a FK relationship
具有重要字段的两个表的结构:
TableA: Id (PK), Type
TableB: Id (PK), TableAId (FK), ReferenceId (Self-reference key)
我需要一个约束,它会说:
TableB ReferenceId 列可以并且必须包含一个值,仅当 TableAId 值指向类型值 > 1 的记录时。
我该怎么做?
一种不需要触发器的方法具有数据冗余。
将 type
列放入表 B 中,并在其中添加一个约束。并为外键向 TableA 添加一个额外的唯一键:
create table tableA (
id int primary key,
type int,
constraint unq_type_id unique (type, id)
);
create table tableB (
id int primary key,
type int,
tableAID int,
constraint fk_tableB_type_tableAID foreign key (type, tableAID) references tableA(type, id),
constraint chk_type check (type > 1)
);
这是一个 hack,但它确实可以在没有触发器的情况下完成你想要的。
此方法的一个变体不需要在两个表中重复 type
,但它确实需要额外的列:
create table tableA (
id int primary key,
type int,
typeIsValid as (case when type > 1 then 1 else 0 end) persisted,
constraint unq_type_id unique (typeIsValid, id)
);
create table tableB (
id int primary key,
tableAID int,
typeIsValid as (1),
constraint fk_tableB_typeIsValid_tableAID foreign key (typeIsValid, tableAID) references tableA(type, id) persisted
);
这甚至适用于 SQL Fiddle。
具有重要字段的两个表的结构:
TableA: Id (PK), Type
TableB: Id (PK), TableAId (FK), ReferenceId (Self-reference key)
我需要一个约束,它会说:
TableB ReferenceId 列可以并且必须包含一个值,仅当 TableAId 值指向类型值 > 1 的记录时。
我该怎么做?
一种不需要触发器的方法具有数据冗余。
将 type
列放入表 B 中,并在其中添加一个约束。并为外键向 TableA 添加一个额外的唯一键:
create table tableA (
id int primary key,
type int,
constraint unq_type_id unique (type, id)
);
create table tableB (
id int primary key,
type int,
tableAID int,
constraint fk_tableB_type_tableAID foreign key (type, tableAID) references tableA(type, id),
constraint chk_type check (type > 1)
);
这是一个 hack,但它确实可以在没有触发器的情况下完成你想要的。
此方法的一个变体不需要在两个表中重复 type
,但它确实需要额外的列:
create table tableA (
id int primary key,
type int,
typeIsValid as (case when type > 1 then 1 else 0 end) persisted,
constraint unq_type_id unique (typeIsValid, id)
);
create table tableB (
id int primary key,
tableAID int,
typeIsValid as (1),
constraint fk_tableB_typeIsValid_tableAID foreign key (typeIsValid, tableAID) references tableA(type, id) persisted
);
这甚至适用于 SQL Fiddle。