2011-04-08 147 views
1

我有兩個表如下:衝突觸發器

  • department(alpha, college, etc.)
  • course(id, alpha, college, title, etc.)

學院和α都存在通過設計兩個表英寸我決定取消一些標準化因爲大學和阿爾法在觀看課程時總是需要。

我有一個觸發該department表更新後,以便更新在course表中的所有行與新alphacollege值執行。我也有更新course表,以確保在alpha之前執行觸發器 - college對用戶在他或她的編輯提交的department表存在;如果這對不在那裏,會引發和應用程序錯誤。

這些觸發衝突。第二個檢查department表的新值是否在其中,但它們尚未如此,因此它應該失敗。

是否有可能,如果是第一次執行的第一個觸發器忽略第二觸發?我真的不想在這種情況下執行第二個觸發器,因爲我知道這些值在第一個表中。如果這是不可能的,有沒有更好的方式來做到這一點,而不改變我的模式?

回答

3

你的第二個觸發聽起來沒有什麼比一個外鍵更變量的值的第二觸發。取而代之的是在course上創建外鍵約束。這在我的測試中起作用。

然而,似乎是不必要的工作來支持提供很少好處的非規範化。如果您只想編寫簡單的查詢,請創建一個視圖來加入這兩個表並在查詢中使用它。如果您擔心連接性能,我非常懷疑這會是一個問題,除非您在表上缺少明顯的索引。

+0

我想我可能會這樣做。我通常不是DBA,但他被公共汽車撞到了。 – geowa4 2011-04-08 17:05:22

2

我會真誠地建議刪除你的觸發方式都在一起,因爲它是通過負擔髒讀。每當遇到像這樣的挑戰時,我只會使用存儲過程來實現DML。如果正確實施,您可以輕鬆獲得觸發器的所有優點。

如果你怕是要確保部門表中的所有更新按照你的邏輯,做過程變化,刪除更新權限的任何用戶,除了存儲過程的所有者。這確保了唯一可以修改該表的調用者是您控制和理解的存儲過程。巧合的是,它成爲更新表格的唯一方法。

只需$ 0.02

+0

我想這樣做,如果沒有其他方式。我只是不想再做任何存儲過程。 :-P – geowa4 2011-04-08 00:40:55

+1

這是一個很好的建議,但是編寫存儲過程不能替代聲明適當的完整性約束 - 在這種情況下,從外部到外部的外鍵。約束將有助於確保您的代碼是正確的。 – 2011-04-08 13:20:27

+0

優秀點Dave =)+1給你 – Pepto 2011-04-08 20:22:13

2

像使用觸發器來實現其他大多數情況下,你可以看到這裏的負擔,因爲數據模型本身有缺陷。

您可以實現相同的邏輯如下,保持使用PK和FK約束的所有規則。

---Department references College... 

Create table department(
    department_id number primary key, 
    aplha varchar2(20) not null, 
    college varchar2(20) not null 
); 

***--Course belongs to a department.. so should be a child of department. 
--If it's possible for different depts to give the same course (IT and CS), 
--you'll have 
--a dept_course_asc table*** 

Create table Course(
    course_id number primary key 
    department_id number references department(department_id), 
    course_name varchar2(100) not null 
); 

如果您有學生表,您可以將其與另一個student_table關聯表關聯起來。

可能會出現這些數據表比您顯然多得多,但是如果您希望避免數據冗餘並且不希望在父表中更改父表時更新所有表中的列,以上型號是唯一的選擇。

+0

alpha是部門。您已將數據添加到此問題。你的大學表是完全沒用的。 – geowa4 2011-04-08 16:44:43

+0

您添加的唯一好處(一旦我拿走了您添加的數據)就是fk。但是,就像我在問題中所說的那樣,我通過將部門中的一個字段複製到課程來避免單個字段的聯合,從而將其解除規範化。如果你爭辯說我應該每次都加入,那就說出來。 – geowa4 2011-04-08 16:57:56

+0

夠公平的。我同意我根據以前見過的其他問題添加數據,但我無法真正理解「alpha」意味着「部門」。現在修改帖子。是的,我相信你應該根據僞造關鍵部門ID加入兩張表格,而不是阿爾法和大學。 – 2011-04-08 17:43:11

0

有對問題有兩種可能的解決方案。

解決方案1:使用DEFERRABLE FK約束。

此解決方案僅適用於(alpha,college)組合是唯一的並且可以定義爲部門表的PK。 在這種情況下,您不需要課程表上的觸發器。

相反,您定義了一個DEFERRABLE FK(alpha,college)當然是引用了部門表。

而在更新部門之前,您必須執行SET CONSTRAINT ... DEFERRED語句see documentation。 然後FK將不會被驗證,直到提交。

解決方案2:使用系統上下文

您關掉使用本地system_context第二觸發。

必須先創建上下文。 see User Created Contexts

部門觸發器將上下文中的變量設置爲某個值。

並在課程,你檢查的背景下