【问题标题】:Order of execution of trigger and statements in Oracle stored procedureOracle存储过程中触发器和语句的执行顺序
【发布时间】:2013-07-17 07:16:24
【问题描述】:

以下是我的表结构:

Table -Customer
CustomerID Blacklisted Customer Name
101 Y ABC
102 Y DEF

Table -Blacklist
CustomerID BlacklistID Customer Name
101 1011 ABC
102 1012 DEF

Table -Reason
BlacklistID ReasonID Reason Code
1012 02 Rcode2

主表“客户”用于存储客户信息。如果有人将客户表中的黑名单更新为Y,则在“客户”表更新后会触发在“黑名单”表中插入记录。 如果满足以下条件,我们会将客户列入黑名单,

  • 客户表中的黑名单列作为值“Y”和。
  • 黑名单和原因表中有客户记录

现在我的要求是从后端将客户列入黑名单。为此,我正在编写带有以下查询的存储过程:

  1. 更新客户集 blacklisted ='Y' where customerid='102';
  2. select BlacklistID into var_id from blacklist where customerid='102';
  3. 插入原因(BlacklistID,ReasonID,ReasonCode)值(var_id,111,'RCODE1');

现在要在 Reason 表中插入条目(步骤 3),我需要 BlacklistID 这是一个外键,一旦客户表上的触发器被执行,我将获得 BlacklistID 的值。所以我的困惑是,我可以假设在 cntrl 到达我的 INSERT INTO 原因(第 3 步)语句之前,“客户”表的更新触发器将始终被执行。请建议。

【问题讨论】:

    标签: oracle11g


    【解决方案1】:

    如果需要确定触发器的执行顺序,可以在创建触发器时指定这个顺序。

    这是通过 create trigger 语句的 FOLLOWS ...PRECEEDS ... 选项完成的:

    手册中的更多详细信息:http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/create_trigger.htm#CJAEJAFB

    关注 |前文

    指定具有相同时间点的触发器的相对触发。它在创建跨版本触发器时特别有用,它必须按特定顺序触发才能实现其目的。

    使用 FOLLOWS 指示正在创建的触发器必须在指定触发器之后触发。您可以为常规触发器或正向跨版触发器指定 FOLLOWS。

    使用 PRECEDES 指示正在创建的触发器必须在指定的触发器之前触发。您只能为反向跨版触发器指定 PRECEDES。

    【讨论】:

    • 很好的回答来反驳我关于订购的评论,但这实际上只是一个旁注。最初的问题是关于单独的陈述。
    • 我这样做了question,如果我使用 follow 那么我可以获取序列 id 并更新其他触发器的 id 吗?
    【解决方案2】:

    是的。触发器是语句的一部分。尽管您不能完全确定 *) 同一语句中的多个触发器的执行顺序,但您可以确定它们都在语句本身完成时完成。所以到第 2 步时,第 1 步的所有更新触发器都已触发。

    *) 其实默认顺序是:

    1. 触发器之前的语句级别
    2. 触发器之前的行级别
    3. 触发器后的行级别
    4. 触发器后的语句级别

    但是,如果您在触发器之前有两个行级别,默认情况下您无法确定这两个执行的顺序。但是我从 cmets 中了解到,在 Oracle 11 中,您实际上可以指定顺序以涵盖这些情况。

    【讨论】:

    • 感谢您的回复。
    • 可以指定触发器的顺序。参见手册:docs.oracle.com/cd/E11882_01/appdev.112/e25519/…
    • 从 11.1 开始,可以使用 CREATE TRIGGER 上的 FOLLOWS 语法来保证触发器的执行顺序。 docs.oracle.com/cd/B28359_01/appdev.111/b28370/…
    • 各位,感谢您的加入。我还在10,但我会改变答案。请注意,关于订购的评论只是一个旁注。这个问题(我在第一段中回答)是关于单独的陈述,所以它不适用于那里。
    【解决方案3】:

    我认为不需要所有这些表,因此不需要触发器。

    为什么不直接在客户表中使用黑名单原因代码?黑名单表的用途尚不清楚,因为它似乎没有添加任何数据,只是重复了客户表中的数据,并带有一个额外的 id 列?

    或者,如果您需要多个原因代码,那么只需使用引用客户 ID 和原因代码的 blacklist_reason 表——我认为您甚至不需要客户表中的黑名单列。

    【讨论】:

    • 嗨大卫,这些不是实际的表结构:) 我的实际表包含超过 10-12 列。上面的快照只是为了解释场景。表和触发器一切都已经到位,我不能删除/添加任何东西。根据客户的一些新的附加要求,我必须从后端进行黑名单。
    猜你喜欢
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 2019-03-25
    • 2020-05-20
    • 1970-01-01
    • 2021-04-30
    相关资源
    最近更新 更多