首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多列检查约束

多列检查约束
EN

Stack Overflow用户
提问于 2022-02-23 20:35:42
回答 2查看 36关注 0票数 -1

考虑一张简单的桌子。

代码语言:javascript
复制
create table dbo.car(    car_guid UNIQUEIDENTIFIER default(newid()) 
                      ,  car_type varchar(20) not null
                      ,  wind_protector varchar(20) not null
)

insert into dbo.car(car_type, wind_protector) VALUES('HARD_TOP', 'NA')
insert into dbo.car(car_type, wind_protector) VALUES('CONVERTIBLE', 'FLAPBLAST_3')
insert into dbo.car(car_type, wind_protector) values('CONVERTIBLE', 'FLAPBLAST_2')

我试图创建一个检查约束,如果car_type是“可转换的”,那么wind_protector可以是"FLAPBLAST_2“或"FLAPBLAST_3”。否则,wind_protector的值是"NA“。列不能为空。

我写了基本的检查约束。

代码语言:javascript
复制
([wind_protector]='FLAPBLAST_3' OR [wind_protector]='FLAPBLAST_3')

我不得不跨两列编写check约束,并使用and或逻辑。

有可能做我想要完成的事情吗?

谢谢,

EN

回答 2

Stack Overflow用户

发布于 2022-02-23 20:44:23

我认为你是在追求以下约束:

代码语言:javascript
复制
alter table car 
add constraint chk1 
check (
  ( car_type='CONVERTIBLE' and wind_protector in ('FLAPBLAST_2','FLAPBLAST_3')) 
    or wind_protector='NA' 
);
票数 1
EN

Stack Overflow用户

发布于 2022-02-23 22:51:27

您可以使用AND OR逻辑使用一个简单的多列约束来完成这一任务。

代码语言:javascript
复制
CHECK (
    car_type = 'CONVERTIBLE' AND wind_protector IN ('FLAPBLAST_2', 'FLAPBLAST_3')
    OR
    car_type = 'CONVERTIBLE' AND wind_protector = 'NA'
)

但是这里不需要一个check 约束, wind_protector不是Car的属性,而是CarType的属性。它可以有多个wind_protector

因此,您需要将模式规范化为适当的第三范式。您还需要几个表:CarType,它包含每个car类型。然后,WindProtector表包含可能的风力保护器选项。最后,一个连接它们并定义哪些组合是可能的表:

代码语言:javascript
复制
create table dbo.CarType (
    car_type varchar(20) not null primary key
);

insert dbo.CarType (car_type) VALUES
('HARD_TOP'),
('CONVERTIBLE');

create table dbo.WindProtector (
     wind_protector varchar(20) not null primary key
);

insert dbo.WindProtector (wind_protector) VALUES
('NA'),
('FLAPBLAST_2'),
('FLAPBLAST_3');

create table dbo.CarOptions (
     options_id int not null primary key  -- surrogate key
  ,  car_type varchar(20) not null references CarType (car_type)
  ,  wind_protector varchar(20) not null references WindProtector (wind_protector)
  ,  unique (car_type, wind_protector)
);

insert into dbo.CarOptions (options_id, car_type, wind_protector) VALUES
(1, 'HARD_TOP', 'NA'),
(2, 'CONVERTIBLE', 'FLAPBLAST_3'),
(3, 'CONVERTIBLE', 'FLAPBLAST_2');

create table dbo.Car (
    car_guid UNIQUEIDENTIFIER default(newid()) 
 ,  option_id int not null references CarOptions (options_id)
);

insert dbo.Car (option_id) VALUES
(1),
(2),
(3);

db<>fiddle

根据需求,您可能希望将CarCarOptions合并到一个表中。

我还建议使用NULL而不是'NA'

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71243728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档