2011-01-19 8 views
4

別のテーブルの推定時間に加えられた変更を記録するテーブルを作成しようとしています。データベース全体は、企業が従業員に作業を割り当て、顧客に請求書を作成するためのプロジェクト管理システムです。日付が未来でないことを確認するための制約をチェックしますか?

は現在、私は持っている:CHANGE_DATEは将来の日付でなければなりません

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) 
); 

、それが今日または過去のいずれかでなければなりません。 最後のチェック制約が問題です。私が理解しているように、あなたが忘れてしまった理由のためにsysdateを使うことはできませんが、できません。私はGETDATE()と私がオンラインで見つけたすべての変種も試しました。 これはおそらく単純な作業ですか?

+1

'GETDATE()'はTSQL固有のものです。 'SYSDATE'は現在の日時を取得するためのPLSQL固有の手段であり、' CURRENT_TIMESTAMP'はANSIの代替手段です(データベースの大半がサポートしています)。実際にエラーが発生していますか?これはSYSDATEを使用しないことについて私が聞いた最初のものなので、もっと聞きたいです。ご使用のOracleのバージョンも役立ちます。 –

答えて

-2

私はあなたがチェックを実行し、チェック制約でそれを使用するユーザー定義関数を定義できると思います。

+0

-1 Oracleはチェック制約にUDFを許可していません – Andomar

+0

チェック制約 –

+0

+1からユーザー定義関数を呼び出すことはできませんが、仮想列 –

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

+1を使用することは可能ですあなたはおそらく '> sysdate'と書いていました。 – Andomar

+0

@Andomar - D'oh。はい、あなたが正しい。私はその訂正をした。 –

1
CONSTRAINT TASKHIST_CHANGEDATE_NONFUTURE CHECK (change_date <= sysdate) 

つまりこれは、制約として、本当に問題となる、チェック制約から機能を呼び出すことはできません。 行(ある他の列)を更新するか、制約を無効/無効にする場合に何が起こるかを考慮してください。元の日付と照合するのではなく、current SYSDATE!

テーブルに別の列を追加し、デフォルトでSYSDATEを指定し、新しい列(stored SYSDATE)とchange_dateを比較する制約またはトリガを構築することを推奨します。

関連する問題