2015-03-02 69 views
2

我正在創建一個應該檢查各種日期約束的表,但是oracle對這個參數很感興趣。我的目標是要預留一定的空間,比方說,一個演講,所以我因子評分的是這樣的:在oracle中檢查約束操作中的DDL日期數據類型

.... prenotation_date日期NOT NULL, starting_date日期NOT NULL, ENDING_DATE日期NOT NULL,

檢查(/ strarting_date> prenotation_date + 3GG /) - >您可以預定時間後只有3天的房間,你要問的預訂

檢查(/ * starting_date = ENDING_DATE * /)中的問候您要預訂日期,意思是你c在的時間方面的書的房間,爲期一天

檢查(/ * starting_date < ENDING_DATE * /)你考慮,這意味着在女巫的時候,你開始使用的房間必須你打算離開房間的時間較早(假設你想保留它從上午8:00到上午10:00

問題是我不知道如何考慮只是一部分數據,但我想有一種方法可以實現這一點,否則你應該創建4列而不是2,並用於一對夫婦假日期和另一個愚蠢的時間,這對我來說似乎很笨拙。所以我想問題是,我如何在單個組件中考慮日期類型?這甚至可能嗎?感謝您對長篇文章的關注和遺憾。

+0

檢查約束就足夠了。我爲每個檢查的條件提供了一個完整的測試用例。看到我的答案。 – 2015-03-02 11:10:23

+0

這裏的答案是正確的,但邏輯很容易出錯。當老闆說「現在預訂房間」時會發生什麼?你打算告訴他們:「我必須更改生產數據庫上的代碼嗎?」考慮一個單獨的表格,其中「這些將永遠不會改變」數字作爲值。然後在觸發器中引用它們而不是硬編碼值。 – kevinsky 2015-03-02 14:09:31

回答

2

你可以使用一個CHECK約束下列條件:

  1. starting_date> prenotation_date + 3
  2. starting_date < ENDING_DATE
  3. TRUNC(starting_date)= TRUNC(ENDING_DATE)

starting_date > prenotation_date + 3將確保預訂是allo在預訂3天后結婚

starting_date < ending_date將確保預訂時間始終在離開時間之前。

TRUNC(starting_date) = TRUNC(ending_date)將確保預訂在同一天完成。 這就是預訂窗口只有一天。

測試用例:

CREATE TABLE

SQL> CREATE TABLE t(
    2 prenotation_date DATE NOT NULL, starting_date DATE NOT NULL, ending_date DATE NOT NULL); 

Table created. 

SQL> 

ADD檢查約束

SQL> ALTER TABLE t ADD CONSTRAINT t_chk CHECK(
    2 (starting_date > prenotation_date + 3) 
    3 AND (starting_date < ending_date) 
    4 AND (TRUNC(starting_date) = TRUNC(ending_date)) 
    5 ); 

Table altered. 

SQL> 

INSERT:C heck starting_date > prenotation_date + 3。下面插入應該失敗。

SQL> INSERT 
    2 INTO t VALUES 
    3 (
    4  to_date('03/01/2015 00:00:00','mm/dd/yyyy hh24:mi:ss'), 
    5  to_date('03/02/2015 08:00:00','mm/dd/yyyy hh24:mi:ss'), 
    6  to_date('03/02/2015 10:00:00','mm/dd/yyyy hh24:mi:ss') 
    7 ); 
INSERT 
* 
ERROR at line 1: 
ORA-02290: check constraint (LALIT.T_CHK) violated 


SQL> 

INSERT:檢查starting_date < ENDING_DATE。下面插入應該失敗。

SQL> INSERT 
    2 INTO t VALUES 
    3 (
    4  to_date('02/01/2015 00:00:00','mm/dd/yyyy hh24:mi:ss'), 
    5  to_date('03/02/2015 10:00:00','mm/dd/yyyy hh24:mi:ss'), 
    6  to_date('03/02/2015 08:00:00','mm/dd/yyyy hh24:mi:ss') 
    7 ); 
INSERT 
* 
ERROR at line 1: 
ORA-02290: check constraint (LALIT.T_CHK) violated 


SQL> 

INSERT:檢查被預約在同一天完成。下面插入應該失敗。分別記錄開始和結束時間08:00:0010:00:00的時間。

SQL> INSERT 
    2 INTO t VALUES 
    3 (
    4  to_date('02/01/2015 00:00:00','mm/dd/yyyy hh24:mi:ss'), 
    5  to_date('03/02/2015 08:00:00','mm/dd/yyyy hh24:mi:ss'), 
    6  to_date('04/02/2015 10:00:00','mm/dd/yyyy hh24:mi:ss') 
    7 ); 
    INSERT 
* 
ERROR at line 1: 
ORA-02290: check constraint (LALIT.T_CHK) violated 


SQL> 

INSERT:所有值滿足所述的要求,下面的插入應該通過。

SQL> INSERT 
    2 INTO t VALUES 
    3 (
    4  to_date('02/01/2015 00:00:00','mm/dd/yyyy hh24:mi:ss'), 
    5  to_date('03/02/2015 08:00:00','mm/dd/yyyy hh24:mi:ss'), 
    6  to_date('03/02/2015 10:00:00','mm/dd/yyyy hh24:mi:ss') 
    7 ); 

1 row created. 

SQL> 
+0

很棒的意見,非常感謝。儘管我不明白TRUNC是如何工作的。默認是截斷時間縮短的時間?我強硬的解決方案是與to_date - to_char嵌套函數的東西,以隔離感興趣的參數;順便說一下,我無法去工作。 – darkpirate 2015-03-04 13:53:48

+0

顯然我的想法在邏輯上是正確的,但非常可怕。我試圖比較字符串域中的日期以實現第一次檢查 - > to_char(starting_date,'mm/dd/yyyy')= to_char(ending_date,'mm/dd/yyyy') – darkpirate 2015-03-04 14:02:09

+0

Trunc從時間元素日期。因此,truncted值的日期時間值爲DATE + 00:00:00小時。 – 2015-03-04 15:51:50

0

通常你應該學會如何在Oracle和SQL中使用日期:)有幾種方法可以做到這一點。例如:

-- Check whether room was booked timely 
alter table Reservations add constraint RC1 
    check (trunc(starting_date, 'DD') >= trunc(prenotation_date, 'DD') + 3); 

-- Disable booking ranges around midnight 
alter table Reservations add constraint RC2 
    check (trunc(starting_date, 'DD') = trunc(ending_date, 'DD')); 

-- Check whether booked range exists 
alter table Reservations add constraint RC3 
    check (starting_date < ending_date); 
+0

謝謝,先生。 – darkpirate 2015-03-04 14:02:43

+0

不客氣:) – 2015-03-04 15:32:12