暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 允许空值或不同值的约束

askTom 2018-02-05
203

问题描述

嗨,伙计们,

我想知道是否有可能在表中创建一个约束,该约束在一组项目 * 或 * 唯一值的指定列中允许NULL。

我树立了一个榜样。想象一下,您可以设置一个绝地部队来管理自己,也可以不下达明确的命令,让他们应该履行守卫职责。在这种情况下,你会留下fk_outpost空白-单位自我管理。
或者,您可以下达明确的命令,例如,绝地部队的一半守卫前哨1,一半守卫前哨2。

一个单元可以是
-自我管理,在这种情况下,它将有一个单一的警卫职责,前哨为null
-管理,在这种情况下,该部队可能有许多前哨。那个单位的所有前哨必须不同

您不能混合这两种状态,因此最终选择的第1行和第2行将是非法的,我想防止这种状态发生约束。

我曾考虑过使用触发器,但我认为它在多个会话中并不可靠,对吗?

致以最诚挚的问候,
塞缪尔

专家解答

这里有一种方法来解决这个问题:

-将 “订单管理” 属性添加到具有自我和管理 (或类似) 值的Jedi单位
-传播这个jedi_guard_conrent,当这是:
-托管确保fk_output不为null
-自我确保fk_output为null
-在 (fk_jedi_unit,fk_outpost) 上创建唯一约束

你完了!

create table outpost ( 
    id integer not null primary key 
);

insert into outpost values ( 1 );
insert into outpost values ( 2 );

create table jedi_unit ( 
    id integer not null primary key, 
    members integer default 10 not null ,
    order_management varchar2(10) not null,
    unique (id, order_management)
);

insert into jedi_unit values ( 1, 10, 'SELF' );
insert into jedi_unit values ( 2, 10, 'MANAGED' );
insert into jedi_unit values ( 3, 10, 'SELF' );

create table jedi_guard_contingent ( 
    id integer not null primary key,
    fk_jedi_unit integer not null, 
    order_management varchar2(10) not null, 
    fk_outpost integer, 
    used_members integer not null, 
    constraint jgc_fk_unit foreign key ( fk_jedi_unit, order_management ) 
      references jedi_unit( id, order_management ), 
    constraint jgc_fk_outpost foreign key ( fk_outpost ) references outpost( id ) ,
    constraint jgc_output_managed_c check ( 
      case when order_management = 'MANAGED' then fk_outpost else 1 end is not null 
    ),
    constraint jgc_output_self_c check ( 
      case when order_management = 'SELF' then fk_outpost end is null 
    ),
    unique (fk_jedi_unit, fk_outpost)
);

insert into jedi_guard_contingent values ( 1, 1, 'SELF', null, 5 );
insert into jedi_guard_contingent values ( 2, 1, 'SELF', 1, 5 );
insert into jedi_guard_contingent values ( 3, 2, 'MANAGED', 1, 5 );
insert into jedi_guard_contingent values ( 4, 2, 'MANAGED', 2, 5 );
insert into jedi_guard_contingent values ( 5, 3, 'SELF', null, 10 );
insert into jedi_guard_contingent values ( 6, 1, 'SELF', 3, 5 );
insert into jedi_guard_contingent values ( 7, 2, 'MANAGED', null, 5 );
insert into jedi_guard_contingent values ( 8, 1, 'SELF', null, 5 );
select * from jedi_guard_contingent;

ID   FK_JEDI_UNIT   ORDER_MANAGEMENT   FK_OUTPOST   USED_MEMBERS   
   1              1 SELF                                   5 
   3              2 MANAGED                       1              5 
   4              2 MANAGED                       2              5 
   5              3 SELF                                  10 
复制


根据您要管理对jedi_guard_conrent的更改的方式,您可能希望创建FK到jedi_unit可延迟。这允许您更新单元的订单管理属性。然后更改其分配。

I thought about using triggers, but I think it won't be reliable with multiple session then, would it?

使用触发器可以做到这一点。但这很棘手,可能会犯错误。

并感谢很酷的测试用例;)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论