簡體   English   中英

Oracle中的觸發器,之前/之后,語句級/行級

[英]Triggers in Oracle, before/after, statement level/ row level

我認為這些概念對我來說很清楚,現在我不太確定。 我是 SQL 的新手並且已經搜索了答案,但似乎太愚蠢了,無法理解可用的內容。

這是一個虛構的情況,也許我可以得到一些見解。 假設我有一個名為注冊詳細信息的表,其中包含諸如學生 ID、課程 ID、年級和機構之類的內容。 成績通常在一個季度結束時分配,但如果成績發生變化,可能會在一個季度的中間更新。 如果我要編寫一個計算 GPA 的觸發器...

CREATE OR REPLACE TRIGGER gpa_calc
BEFORE UPDATE OF course_grade
ON enroll_details
FOR EACH ROW

如果改變會如何

  1. 我將 BEFORE 更改為 AFTER
  2. 從 FOR EACH ROW 更改為語句級別。

如果我將 BEFORE 更改為 AFTER,我希望會拋出錯誤,因為您正在嘗試更新已寫入內存的表。

如果我從行級別更改為語句級別觸發器,我不確定 GPA 是否會正確計算,因為它不會為每次更新觸發...

任何幫助,將不勝感激。

oracle中觸發器前后的區別

觸發器可以修改要更新/插入的數據,因此它們對於執行數據完整性規則或提供默認值很有用。 在提交事務之前,觸發器將立即運行,並且無法進行任何更新。 它們是執行驗證或更新匯總表的正確位置,在這些地方您要確保不能進一步更改源值。

在您的示例中,gpa大概存儲在單獨的表中(因為它不是所采用的任何單個類的屬性),因此它很可能是after觸發器。 如果您要添加觸發器以基於一些復雜的邏輯來修改成績(例如,如果GPA> 4.0構成一個愚蠢的示例,那么您的得分不能低於C),那么這將是之前的觸發器在更新表格之前更改成績。

要添加的是,對於要更新的​​每一行都調用FOR EACH ROW觸發器(顧名思義),您可以訪問:old和:new。 無論更新了多少行,語句級觸發器都會被調用一次,並且您無權訪問各個:new或:old值。 這對於基於復雜條件(可能不允許在晚上10點至晚上11點之間進行更新)強制/阻止訪問,或者將表標記為“臟”並需要稍后的批處理模式任務進行處理(例如,導出到數據)非常有用。倉庫)。

AskTom提供的更多信息: https ://asktom.oracle.com/pls/asktom/f ? p = 100:11:0::::P11_QUESTION_ID:29259877603106

計算值將復雜性引入模型。 通常,維護它們的成本超過了按需計算它們的成本(取決於讀寫之間的平衡)。 但是有時值對於應用程序來說是如此重要,以至於我們始終需要掌握它。 也許我們需要對其進行審核。 假設GPA是這些屬性之一。

因此,關於GPA的幾點要點:

  1. GPA是根據所有學生的成績計算出來的(因為這是平均水平 )。 如果對三個等級進行了修改,我們只需計算一次新的GPA。 因此,我們不想使用FOR EACH ROW觸發器,因為在那種情況下,它將觸發3次。 除了將相同的計算運行三遍而明顯的效率低下外,最有可能會因變異表錯誤而失敗(因為數據庫足夠聰明,可以知道正在更改三個記錄,所以我們想要哪個版本?)
  2. GPA是學生的屬性。 因此,計算GPA不會更改enroll_details表的狀態,因此BEFORE或AFTER觸發器無關緊要(但請參閱下文)。

通常,我們使用BEFORE觸發器來驗證和驗證值,應用計算的默認值以及我們希望進行的任何處理,而與是否應用行無關。 我們使用AFTER觸發器進行處理,假設已應用該行。 計算GPA之類屬於第二類。 因此,觸發器應該是AFTER語句級觸發器:

CREATE OR REPLACE TRIGGER gpa_calc
    AFTER UPDATE OF course_grade
    ON enroll_details

這是我考試中有人試圖抄襲/獲得互聯網答案的問題。

它應該從 StackOverflow 中刪除

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM