2016-07-30 56 views
0

在將數據插入表之前,哪種方式更好地驗證數據的輸入,使用CHECK約束還是使用if語句?有更好的方法來驗證它嗎?在INSERT語句中使用CHECK約束來驗證數據是一種很好的做法

1)

DECLARE 
INVALID_DATE EXCEPTION; 
... 
-- Check if date is valid 
IF TO_DATE(dt,'DD/MM/YYYY') > TO_DATE('10/10/2010','DD/MM/YYYY')THEN 
RAISE INVALID_DATE; 
END IF; 

-- Insert data only if it is valid 
INSERT INTO Table VALUES(dt); 

EXCEPTION 
WHEN INVALID_DATE 
     THEN DBMS_OUTPUT.PUT_LINE('Date is not valid'); 
... 

2)

... 
-- Do NOT check if date is valid and let an 
-- CHECK constraint exception(CH_TABLE1) be raised if it is invalid 
INSERT INTO Table VALUES(dt); 

EXCEPTION 
WHEN CHECK_CONSTRAINT_VIOLATED THEN 
    IF SQLERRM LIKE 'ORA-02290:%CH_TABLE1%' THEN 
     DBMS_OUTPUT.PUT_LINE('Date is not valid'); 
    ... 
    END IF; 
... 

回答

1

這取決於 - 通常需要多層方法。

例如,您可能有一組簡單的業務規則,可以直接在數據庫中維護爲檢查約束。我只將這些用於簡單的,獨立的檢查。

- 檢查Y/N標誌:

alter table example_table add constraint ck_example_table_flag 
check (flag is null or flag in ('Y', 'N'); 

在這種情況下,如果您在本專欄中得到任何其他的價值,你知道的數據是不好的,這是不是一個規則隨着時間的推移會發生變化。添加此約束將防止任何應用程序破壞您的數據。

對於更復雜的業務規則,可能不是自包含的,例如,如果某個日期取決於輸入值的人或另一個表中另一個字段的內容,那麼我會在「應用程序」 。

有時'應用'數據庫 - 在這種情況下,您的檢查約束可能在表觸發器或打包的pl/sql中處理所有表更新。例如:

example_app.update_data(id => 1000, value => 'foo'); 

這是怎麼你的數據更新的處理方式,有什麼不對處理您的業務規則檢查約束,觸發與檢查,或直接在update_data程序。

在許多企業環境中,應用程序層和數據庫層將由不同的團隊處理。如果您在支持應用程序層的團隊中,您可能會發現,爲數據庫團隊提出更改請求來放置檢查約束是非常痛苦的 - 在這種情況下,嚮應用程序層添加一些邏輯會感覺更多直截了當。相反,數據庫團隊可能會發現它更直接。

@Bohemian makes an excellent point關於在有多個客戶端時使用檢查約束來強制數據完整性。

1

如果更新/插入可以來自多個應用程序/腳本,特別是即席查詢,然後檢查約束使所需的業務邏輯在一個這是一件好事的地方。

如果更新/插入來自一個應用程序/源,則最好在應用程序中執行檢查(在本例中爲存儲過程)。

有一個檢查約束是一個捕獲所有,但它有點隱藏。

1

支持使用檢查約束的另一個考慮因素是它們可以通過允許優化器推斷某些值不能出現在表中來提高性能。

在約束的存在限制日期列來檢查:

my_col>日期「2010-01-01」

...使用謂詞例如查詢:

my_col = date'2009-01-01'

...可以確定沒有行將從該表中返回。

相關問題