2014-04-23 18 views
3
CREATE TABLE LOCATION (
    LOCID VARCHAR2(5) 
, MINQTY NUMBER 
, MAXQTY NUMBER 
, PRIMARY KEY (LOCID) 
, CONSTRAINT CHECK_LOCID_LENGTH CHECK (LENGTH(LOCID) = 5) 
, CONSTRAINT CHECK_MINQTY_RANGE CHECK (MINQTY BETWEEN 0 AND 999) 
, CONSTRAINT CHECK_MAXQTY_RANGE CHECK (MAXQTY BETWEEN 0 AND 999) 
, CONSTRAINT CHECK_MAXQTY_GREATER_MIXQTY CHECK (MAXQTY >= MINQTY) 
); 


CREATE OR REPLACE PROCEDURE ADD_LOCATION_TO_DB(ploccode VARCHAR2, pminqty NUMBER, pmaxqty NUMBER) AS 
BEGIN 
INSERT INTO location(locid, minqty, maxqty) VALUES (ploccode, pminqty, pmaxqty); 
EXCEPTION 
WHEN DUP_VAL_ON_INDEX THEN 
RAISE_APPLICATION_ERROR(-20081, 'Duplicate Location ID'); 
WHEN OTHERS THEN 
RAISE_APPLICATION_ERROR(-20086,sqlerrm); 
END; 

我用約束創建了上表。 現在我想通過在例外中捕獲這些約束來在PL/SQL過程中測試這些約束。但我很困惑如何去做。如何在PL/SQL中捕獲約束違規?

+0

[tag:sql-server]不使用PL/SQL。你需要一個解決方案,它和[標籤:甲骨文]? –

+0

我希望在位置表中插入一行並希望測試該pl/sql過程中的約束的過程的PL/SQL代碼。但我不確定如何檢查約束的代碼。 – Kaash

+0

是的,但是你用兩個*不同的*產品標記了這個問題,其中一個產品甚至沒有PL/SQL。你真的需要兩種產品的解決方案嗎? –

回答

10

違反檢查約束時發生的錯誤是ORA-02290。儘管沒有「標準」的定義,但它很容易宣告你自己的異常,所以你可以在拋出時捕獲-2290。比方說,我們有一個表創建如下:和

CREATE TABLE SOME_TABLE (COL1 CHAR(1) CHECK(COL1 IN ('Y', 'N'))); 

,我們然後運行以下塊:

DECLARE 
    -- First, declare and initialize an appropriate exception 

    CHECK_CONSTRAINT_VIOLATED EXCEPTION; 
    PRAGMA EXCEPTION_INIT(CHECK_CONSTRAINT_VIOLATED, -2290); 
BEGIN 
    INSERT INTO SOME_TABLE(COL1) VALUES ('X'); -- will violate the check constraint 
    RETURN; 
EXCEPTION 
    WHEN CHECK_CONSTRAINT_VIOLATED THEN -- catch the ORA-02290 exception 
    DBMS_OUTPUT.PUT_LINE('INSERT failed due to check constraint violation'); 
    WHEN OTHERS THEN      -- catch all other exceptions 
    DBMS_OUTPUT.PUT_LINE('Something else went wrong - ' || SQLCODE || 
         ' : ' || SQLERRM); 
END; 

如果創建表如上文所示,然後運行上面你就會塊發現DBMS_OUTPUT上顯示'INSERT因檢查約束違規而失敗'這一行。

分享和享受。

+0

如果表中有多個檢查約束,是否有辦法確定違反了哪個約束? –

+0

我相信,約束的名稱將與其他文本一起在SQLERRM中。您可以如上所示打印SQLERRM,或者解析文本以查找約束名稱。 –