表列的顺序约束

时间:2014-07-17 12:44:18

标签: sql oracle constraints

说我有一个包含createduploadedprocessedarchived列的表格,所有这些列都接受日期。但是,我想要它,所以字段必须按时间顺序更新,你不能跳过一个步骤,但不必设置尾随步骤,直到它们准备好(即创建) < = uploaded< = processed< = archived)。我这样实现了这个:

create table batch (
  id        number primary key,
  created   date   default sysdate not null,
  uploaded  date,
  processed date,
  archived  date,

  check (uploaded  is null or uploaded  >= created),
  check (processed is null or processed >= uploaded),
  check (archived  is null or archived  >= processed)
);

这有效,但它允许您跳过步骤。例如,如果processed仍为uploaded,我可以为null插入任意值。我认为这是因为null比较总是空洞的。因此,我必须做以下事情:

create table batch (
  id        number primary key,
  created   date   default sysdate not null,
  uploaded  date,
  processed date,
  archived  date,

  check (uploaded  is null or uploaded >= created),
  check (processed is null or (uploaded is not null and processed >= uploaded)),
  check (archived  is null or (processed is not null and archived >= processed))
);

有更简洁的方法吗?

3 个答案:

答案 0 :(得分:2)

我认为你的设计很健全。我会按时间顺序和NULL检查拆分检查,但这只是样式的问题,而不是逻辑问题。

create table batch (
  id        number primary key,
  created   date   default sysdate not null,
  uploaded  date,
  processed date,
  archived  date,

  CHECK (created <= uploaded),
  CHECK (uploaded <= processed),
  CHECK (processed <= archived),

  CHECK (uploaded IS NOT NULL OR processed IS NULL),
  CHECK (processed IS NOT NULL OR archived IS NULL)
);

答案 1 :(得分:1)

最后,我选择了自己的解决方案:

create table batch (
  id        number primary key,
  created   date   default sysdate not null,
  uploaded  date,
  processed date,
  archived  date,

  check (uploaded  is null or uploaded >= created),
  check (processed is null or (uploaded is not null and processed >= uploaded)),
  check (archived  is null or (processed is not null and archived >= processed))
);

当然,正如Jorge所提到的那样,这限制了这个静态模式的工作流程,但这是我愿意接受的权衡!

答案 2 :(得分:0)

您可以创建4个表格。每个过程一个。

  1. batches_created
  2. batches_uploaded
  3. batches_processed
  4. batches_archived
  5. create table batches_created (  
      id        number primary key,  
      created   date   default sysdate not null  
    );
    
    create table batches_uploaded (  
      id        number primary key,  
      created   date   default sysdate not null,  
      constraint fk_batch_uploaded FOREIGN KEY( id ) REFERENCES batches_created( id )  
    );
    
    create table batches_processed (
      id        number primary key,  
      created   date   default sysdate not null,  
      constraint fk_batch_processed FOREIGN KEY( id ) REFERENCES batches_uploaded( id )  
    );
    
    create table batches_archived (  
      id        number primary key,  
      created   date   default sysdate not null,  
      constraint fk_batch_archived FOREIGN KEY( id ) REFERENCES batches_processed( id )  
    );
    

    因此,如果没有先创建批处理,上传它,然后处理它,就不能存档。