2014-04-17 86 views
2

我有客戶 - > |級聯規則| - > orders_table - > |級聯規則| - > ORDER_DETAILS 在我ORDER_DETAILS我已經刪除後觸發遞增的數量在我的產品表火鳥停用觸發

CREATE OR ALTER TRIGGER TABLEAU_DETAIL_VENTES_AD0 FOR TABLEAU_DETAIL_VENTES 
ACTIVE AFTER DELETE POSITION 0 
AS 
    declare variable qte numeric_15_2; 
begin 
    select qte_article from tableau_articles where id_article = old.id_article 
    into :qte; 
    qte = :qte + old.qte; 
    update tableau_articles 
    set qte_article = :qte 
    where id_article = old.id_article; 
end 

如果我刪除一個客戶端而不是所有的訂單,取決於它將被刪除 和orders_detail等。

問題是,刪除觸發器後的order_details將被觸發並增加產品數量,我不希望發生這種情況。

我的問題:有什麼辦法來知道觸發器是否已經被來自應用程序的級聯規則或sql刪除語句觸發?

我想實現這樣的:

如果觸發通過級聯規則,然後disable_all_triggers觸發。在此先感謝您的幫助。

+2

也許你可以使用['RDB $ SET_CONTEXT'](http://www.firebirdsql。組織/文件/文件/ reference_manuals/reference_material/HTML/langrefupd25-intfunc-set_context.html)和['RDB $ GET_CONTEXT'](http://www.firebirdsql.org/file/documentation/reference_manuals/reference_material/html/langrefupd25 -intfunc-get_context.html)來實現這一點。 –

回答

2

你可以試着來包裝你刪除代碼的存儲過程的執行語句中/激活

CREATE PROCEDURE DeleteClient(
    ID INTEGER) 
AS 
begin 
    execute statement 'alter trigger TABLEAU_DETAIL_VENTES_AD0 inactive;'; 
    /* 
    Your Delete statement here 
    */ 
    execute statement 'alter trigger TABLEAU_DETAIL_VENTES_AD0 active;'; 
END^ 
+0

我想我會使用這個解決方案我會設置所有的規則,不採取行動,並使用存儲過程創建我自己的參照完整性 –

+1

我強烈建議不要使用這個:這可以禁用所有用戶的觸發器! –

+1

正如@Mark在他最初的評論中所說的那樣,使用上下文變量有一個['per transaction way'](http://www.firebirdfaq.org/faq189/)。當你開始一個事務時,你的過程會設置一個上下文變量,並且在觸發器內部,你將檢查該上下文變量,並且如果它處於特定值,則跳過你需要的內容。 – TLama

0

你不能確定,但​​你可以確定你的外鍵是否仍然有效。由於Firebird級聯刪除是順序的(首先刪除在外鍵中引用的行),您可以在更新記錄之前檢查您的old.id_article是否仍然有效。

+0

我想你是誤會了扳機做工精細感謝的 –

+0

@ S.FATEH如果它工作正常的probleme,那麼爲什麼這個問題嗎? –

0

我不確定你會達到你想要的那樣。如果你只是刪除一個訂單及其項目會怎樣。你不想在這種情況下增加數量嗎?

無論如何......我不會停用觸發器內的觸發器。這是糟糕的設計。

使用某種變量...更新支持表中的標誌。從客戶端刪除觸發器內,您可以設置此變量。然後在order_items刪除觸發器中,您可以檢查它是否需要更新數量。

另一個更好的選擇是更好地分析情況並確定爲什麼以及何時實際更新數量。如果您要刪除已完成並交付的舊訂單,則可能不想。如果您要取消新訂單,您可能會這樣做。因此,更新數量實際上更多取決於訂單狀態(或其他變量),然後僅僅是您要刪除order_items行。

好的,所以你說訂單不能刪除,除非刪除客戶端。那麼也許你應該用一個表示客戶端被刪除的標誌來標記客戶端或它的訂單。在order_items刪除觸發器中,僅當客戶端未被刪除時才更新商品數量。

+0

@我的應用程序 Frazz的訂單無法刪除,只能取消並保存爲取消訂單,但你可以刪除/插入/更新的項目,如果你在我的處境要 如果用戶想要刪除客戶端比它的奇怪離開無客戶訂單!如果我依賴firebird的依賴關係,數量會增加,就好像從客戶端返回的產品一樣,我希望擺脫客戶端和所有與它相關的內容而不影響數量 –

+0

在我看來,取消激活觸發器不是一種選擇。我嚴重懷疑你可以在一次交易中做到這一點,而其他交易持續觸發。觸發器用於數據完整性,應視爲常量。我意識到可能需要停用觸發器的唯一時刻就是執行維護腳本或類似事件。這應該在db到用戶和應用程序脫機時完成。隨着您提供的新信息,我會更新我的答案。 – Frazz

1

我最終使用在我的客戶表中的環境變量我添加刪除後觸發,並設置一個標誌trigers在細節訂單使用rdb$set_context

SET TERM^; 
CREATE OR ALTER TRIGGER TABLEAU_CLIENTS_AD0 FOR TABLEAU_CLIENTS 
ACTIVE AFTER DELETE POSITION 0 
AS 
    declare variable id integer; 
begin 
    execute statement 'select rdb$set_context(''USER_SESSION'', ''myvar'', 100) from rdb$database' into :id; 
end 
^ 
SET TERM ;^

檢查我的標誌與rdb$get_context並跳過觸發如果該標誌與相關聯的值存在

select rdb$get_context('USER_SESSION', 'myvar') from rdb$database into :i; 
if (i = 100) then exit;