使用Oracle,如果列值可以为“是”或“否”,是否可以约束表,以便只有一行可以具有“是”值?
我宁愿重新设计表结构,但这是不可能的。
[UDPATE]遗憾的是,此表中不允许使用空值。
答案 0 :(得分:19)
使用基于函数的索引:
create unique index only_one_yes on mytable
(case when col='YES' then 'YES' end);
Oracle仅索引不完全为null的键,此处的CASE表达式确保所有“NO”值都更改为空,因此不会编入索引。
答案 1 :(得分:6)
这是一个kludgy hack,但是如果列允许NULL,那么你可以使用NULL代替“NO”并像以前一样使用“YES”。对该列应用唯一键约束,您将永远不会得到两个“YES”值,但仍然有很多NO。
更新:@Nick Pierpoint:建议添加一个检查约束,以便将列值限制为“YES”和NULL。语法在他的回答中得到了解决。
答案 2 :(得分:4)
您将要查看Tom Kyte的文章,正是询问了这个问题及其答案:
http://tkyte.blogspot.com/2008/05/another-of-day.html
总结:不要使用触发器,不要使用自治事务,使用两个表。
如果您使用的是Oracle数据库,那么您必须了解AskTom并获取他的书籍。
答案 3 :(得分:3)
它不适用于表定义。
但是,如果使用调用存储过程的触发器更新表,则可以确保只有一行包含“YES”。
答案 4 :(得分:2)
继续我的评论到yukondude之前的回答,我会添加一个唯一索引和一个检查约束:
create table mytest (
yesorno varchar2(3 char)
);
create unique index uk_mytest_yesorno on mytest(yesorno);
alter table mytest add constraint ck_mytest_yesorno check (yesorno is null or yesorno = 'YES');
答案 5 :(得分:1)
Oracle是否支持过滤索引(上周我听说过,例如MSSQL2008)?也许您可以定义一个唯一键,它仅适用于列中值为“是”的行。
答案 6 :(得分:-2)
我想我会使用第二个表来指向当前表中的相应行。另一个表也可用于存储其他变量的值。