2012-09-05 70 views
3

我怎樣寫一個Oracle觸發器,當用戶刪除某個記錄比,刪除犯規實際發生的,而是在執行這些行的更新和設置的狀態記錄到'D'?甲骨文TRIGGER-而不是刪除,更新的行

我想:

create or replace 
trigger DELFOUR.T4M_ITEM_ONDELETE 
before delete on M_ITEM_H 
FOR EACH ROW 
BEGIN 
    UPDATE 
    M_ITEM_H 
    SET 
    ITEM_STAT = 'D' 
    WHERE 
    CUST_CODE = 'TEST' 
    AND ITEM_CODE = 'GDAY' 
    ; 

    raise_application_error(-20000,'Cannot delete item'); 
END; 

但我正在逐漸變異表錯誤。這可能嗎?

回答

3

首先你寫會拋出一個變異表錯誤觸發的。從技術上講,你所要求的是不可能的,即刪除不會刪除,而是更新,除非你在中間引發異常,這可能是一種醜陋的方式。我會使用某種應用前端的,它可以讓他們使用刪除按鈕delete數據認爲用戶,所以您可以使用update語句存在,而不是delete聲明。

另一種選擇是創建一個記錄表,在那裏你可以從實際的表中刪除之前插入的記錄,然後加入日誌表與實際的表來獲取刪除的記錄。一些喜歡 -

CRETAE TABLE M_ITEM_H_DEL_LOG as SELECT * FROM M_ITEM_H WHERE 1=2; 

然後

create or replace 
trigger DELFOUR.T4M_ITEM_ONDELETE 
before delete on M_ITEM_H 
FOR EACH ROW 
BEGIN 
    INSERT INTO 
    M_ITEM_H_DEL_LOG 
    VALUES (:old.col1, :old.col2,.....) --col1, col2...are columns in M_ITEM_H 
    ; 
END; 
+0

感謝的!我無權訪問該應用程序。基本上,它是一個倉庫管理系統,如果這個產品沒有任何移動,它將刪除一個商品代碼。如果有,它只是停用該項目。我希望它始終停用該項目。界面使用的是Oracle Forms,因此它非常醜陋,所以我不擔心用戶是否看到oracle的錯誤,因爲當前的應用程序與他們分離。 – Lock

+0

如果你可以更改oracle表單代碼來改變刪除按鈕功能,你可以做到這一點。否則,而不是'不能刪除項目'消息說,像raise_application_error中的'項目已刪除/停用'。 – Annjawn

+0

但要小心突變表錯誤。 – Annjawn

4

如果你真的需要一個觸發,比較合乎邏輯的方法是創建一個視圖,創建視圖的INSEAD OF DELETE觸發,並迫使應用程序根據視圖而不是基表發出刪除操作。

CREATE VIEW vw_m_item_h 
AS 
SELECT * 
    FROM m_item_h; 

CREATE OR REPLACE TRIGGER t4m_item_ondelete 
    INSTEAD OF DELETE ON vw_m_item_h 
    FOR EACH ROW 
AS 
BEGIN 
    UPDATE m_item_h 
    SET item_stat = 'D' 
    WHERE <<primary key>> = :old.<<primary key>>; 
END; 
更好

的是,你會與觸發分配,創建一個delete_item程序,你的應用程序將調用,而不是發出DELETE和程序只會更新該行設置item_stat列,而不是刪除的行。

如果你真的,真的,真的要涉及對錶本身的觸發器的解決方案,你可以

  1. 創建那就是映射到數據記錄的集合成員的包m_item_h
  2. 創建之前刪除語句級觸發器,清空該集合
  3. 創建之前刪除的行級觸發器,插入:old.<<primary key>>和所有其他:old值到集合
  4. 創建一個delete語句級觸發器,遍歷集合,再插入行到表中,並設置item_stat列之後。

這將涉及更多的工作比instead of trigger,因爲你必須刪除,然後重新插入該行,它會涉及更多的移動件,因此它會更不優雅。但它會工作。

+0

不幸的是,我無法訪問該應用程序,所以無法更改此 – Lock

+1

@Lock - 您是否說這是第三方打包應用程序?如果是這樣,爲什麼你可以通過首先添加一個觸發器來修改它? –

+0

因爲我有sysdba訪問數據庫 – Lock