检查约束以确保日期不是将来?

时间:2011-01-19 18:43:52

标签: sql oracle plsql

我正在尝试创建一个表来记录对另一个表的估计小时数所做的更改。整个数据库是一个项目管理系统,供公司为其员工分配工作并为客户创建发票。

目前我有:

CREATE TABLE task_history
(
    task_history_id         NUMBER(5),
    previous_est_hours      NUMBER(3,1),
    change_date         DATE,
    reason_for_change       VARCHAR2(50),
    task_id             NUMBER(5),

CONSTRAINT TASKHIST_TASKHISTID_PK   PRIMARY KEY (task_history_id),
CONSTRAINT TASKHIST_TASKID_FK       FOREIGN KEY (task_id) REFERENCES task(task_id),
CONSTRAINT TASKHIST_TASKID_NN CHECK (task_id IS NOT NULL),
CONSTRAINT TASKHIST_CHANGEDATE_NONFUTURE CHECK (change_date <= sysdate)
);

change_date不能是将来的日期,必须是今天或过去。 最后一个检查约束是问题。据我所知,你不能使用sysdate,因为我忘记了一个原因,但你做不到。我也尝试了GETDATE()以及我在网上找到的所有其他变种。 我怎么能做这个简单的任务呢?

4 个答案:

答案 0 :(得分:10)

您不能从检查约束中调用函数,因此最自然的方法是在task_history表上定义触发器,即

CREATE OR REPLACE TRIGGER task_change_date_in_past
  BEFORE INSERT OR UPDATE ON task_history
  FOR EACH ROW
BEGIN
  IF( :new.change_date > sysdate )
  THEN
    RAISE_APPLICATION_ERROR( -20001, 'Change date must be in the past' );
  END IF;
END;

答案 1 :(得分:2)

在11g中,可以对sysdate使用检查约束:http://rwijk.blogspot.com/2007/12/check-constraints-with-sysdate.html

在11g之前你应该使用贾斯汀的方法。

的问候,
罗布。

答案 2 :(得分:1)

CONSTRAINT TASKHIST_CHANGEDATE_NONFUTURE CHECK (change_date <= sysdate)

作为约束,这将是非常有问题的。 考虑如果要更新行(某些其他列)或停用/响应约束会发生什么。它不会检查原始日期,而是针对current SYSDATE!

我建议在表中添加另一列,默认为SYSDATE,并构建一个约束或TRIGGER,将新列(存储的SYSDATE)与change_date进行比较。

答案 3 :(得分:-2)

我认为您可以定义执行该检查的用户定义函数,并在检查约束中使用它。