plsql

2009-08-24 95 views
2

任何人都可以幫助我編寫一個觸發器來禁止特定的表進入表(例如location ='chicago'不允許)。表模式如下department(deptno,deptname,location)。我正在使用Oracle 10g。plsql

+1

這容易與存儲過程來實現,但我不知道我把它放在那裏是(除非你的開發人員直接在你的數據庫上工作,並且你想限制他們,不太可能),但這些類型的業務約束通常是在代碼中完成的,在數據​​庫之上有很多層。 當然,我對你的代碼或你的設計一無所知,只是一個評論... – Kobi 2009-08-24 09:40:09

回答

11

您可以使用CHECK CONSTRAINT在您的列上輕鬆做到您想要的。

ALTER TABLE T 
ADD CONSTRAINT constraint_name CHECK (location <> 'chicago') [DISABLE]; 

禁用關鍵字是可選的。如果您使用 DISABLE關鍵字創建檢查約束,則將創建約束 ,,但條件 將不會被強制執行

約束美國

  • ENABLE - 確保所有輸入數據是否符合約束
  • DISABLE - 允許傳入的數據,不管它是否符合約束
  • VALIDATE - 確保現有數據符合con straint
  • NOVALIDATE - 現有的數據不必符合約束

這些可以組合使用

ENABLE {[默認] VALIDATE | NOVALIDATE}

DISABLE {VALIDATE | [默認] NOVALIDATE}

  • ENABLE VALIDATE相同ENABLE。

  • ENABLE NOVALIDATE表示檢查約束,但對於所有行不一定是true。這將恢復禁用約束的約束檢查,而不先驗證表中的所有數據。

  • DISABLE NOVALIDATE與DISABLE相同。

  • DISABLE VALIDATE禁用約束,刪除約束上的索引,並禁止對約束列進行任何修改。 對於UNIQUE約束,這使您可以使用ALTER TABLE .. EXCHANGE PARTITION子句將數據從非分區表加載到分區表中。

這是一個BEFORE INSERT觸發器的例子。但是,最好在您的模式上創建約束或實現CUSTOM_INSERT PROCEDURE,以對其進行過濾。 Here是一篇關於的好文章數據完整性 - 約束和觸發器

觸發器不應該被用來執行 業務規則或參照,可以用簡單的約束來實現 誠信 規則。

例觸發(認爲這是一個壞主意過濾輸入):

CREATE TRIGGER myTrigger 
BEFORE INSERT 
ON table 
REFERENCING NEW AS New 
FOR EACH ROW 
    BEGIN 
    IF (New.location = 'chicago') THEN 
     RAISE cError;  
EXCEPTION 
WHEN cError THEN 
     RAISE_APPLICATION_EXCEPTION(-20001,'Chicago is not allowed'); 
END; 
+0

而不是DELETE,應該是RAISE_APPLICATION_ERROR(-20000,'請不要芝加哥!'); – jva 2009-08-24 09:50:38

+0

整個觸發器的東西根本就不需要..而在我的例子中(壞的)觸發器是在... – 2009-08-24 10:12:59

+1

觸發器的缺點是你必須失敗語句。通過檢查約束,開發人員可以選擇使用LOG ERRORS子句,以便插入有效數據並將無效數據放入異常表中。對批量數據加載非常有用。 – 2009-08-24 12:28:56