我有客户 - > |级联规则| - > 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 delete语句触发?
我希望实现以下目标:
如果级联规则触发了触发器,则执行disable_all_triggers。在此先感谢您的帮助。
答案 0 :(得分:2)
您可以尝试使用execute语句将删除代码包装在存储过程中,用于in / activate the trigers
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^
答案 1 :(得分:1)
我最终在我的客户端表中使用上下文变量,我在删除触发器后添加并使用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;
答案 2 :(得分:0)
您无法确定,但您可以确定您的外键是否仍然有效。由于Firebird级联删除是顺序删除(首先删除外键中引用的行),因此您可以在更新记录之前检查old.id_article
是否仍然有效。
答案 3 :(得分:0)
我不确定你会达到你想要的那样。如果您只是删除订单及其商品,该怎么办?在这种情况下你不想增加数量吗?
无论如何......我不会在触发器内停用触发器。这是糟糕的设计。
使用某种变量...更新支持表中的标志。在客户端删除触发器中,您可以设置此变量。然后在order_items删除触发器中,您可以检查它是否需要更新数量。
另一个更好的选择是更好地分析情况并确定您实际想要更新数量的原因和时间。如果您要删除已经履行并交付的旧订单,您可能不会想要。如果您要取消新订单,您可能会这样做。因此,更新数量实际上更多地取决于订单状态(或其他一些变量),然后只是因为您要删除order_items行。
好的,所以你说订单无法删除,除非删除客户端。那么也许你应该用一个标志着客户端被删除的标志来标记客户端或其顺序。在order_items删除触发器中,仅当客户端未被删除时才更新文章数量。