【问题标题】:Missing Insert Record on the table with Trigger (Oracle DB)带有触发器的表上缺少插入记录(Oracle DB)
【发布时间】:2018-07-20 20:20:17
【问题描述】:

场景如下-

  1. 包含“OrderId”和“OrderType”列的OrderTable
  2. 包含“OrderId”和“CustId”列的OrderRelationTable
  3. OrderProcessTable 包含“OrderId”、“OrderType”、“CustId”和“ProcessFlag”列

流程是这样的-

Application1 在 OrderTable 中创建记录 -> 然后使用 MQ 协议将记录传递给 Application2,在这种情况下,Application 2 插入/创建在 OrderRelationTable 中传递的记录 -> 然后在 Oracle DB 中调用触发器来创建记录在 OrderProcessTable 中

问题

有时记录没有插入到表 3 OrderProcessTable 中。不知道是时间问题还是触发器有问题?

Application1 代码



    boolean updated = false;
    /** JDBC prepare statement execution insert into OrderTable in Java**/
    int rowCount = ps.executeUpdate();
    if(rowCount>0){
    updated=true;
    }
    log.log("updated flag:"+updated);
    /** I am able to see the log shows the flag is true, and recored inserted into OrderTable **/

Application2 代码 假设它是一些 Java JDBC 代码插入 OrderRelationTable 并且它是成功的,这并不重要。

触发器

假设语法是正确的。



CREATE OR REPLACE TRIGGER INSERTINTOOrderProcessTable
AFTER INSERT ON OrderRelationTable
FOR EACH ROW DECLEAR
         v_order_type := null;
BEGIN
         SELECT OrderType INTO v_order_type FROM OrderTable
         WHERE OrderId = :new.OrderId
         AND OrderType IS NOT NULL
         AND rownum=1;

      IF v_order_type IS NOT NULL THEN
         INSERT INTO OrderProcessTable VALUES (:new.OrderId, v_order_type, :new.CustId, 'N');
      END IF;
END;

问题 -
  1. 应用程序 1 代码执行后保证 DB 将具有可用于 SELECT 语句的 OrderTable 记录? (假设更新标志为真)
  2. 应用代码和触发器是否存在计时问题?例如,当触发器从 OrderTable 调用 SELECT 语句时? (当然,OrderRelationTable 和 OrderTable 中的订单 id 是匹配的)
  3. 基本上现在我的问题是,有时(很少)记录没有通过触发器插入 OrderProcessTable,即使它应该(订单类型不为空)?有什么想法吗?

【问题讨论】:

  • 你检查过 OrderTable 的 OrderType IS NULL 吗?
  • @P.Salmon 我检查了 OrderTable OrderType 不是 NULL。

标签: sql-server oracle triggers oracle-sqldeveloper


【解决方案1】:

据我所知,没有时间问题

截至触发代码:and rownum = 1 条件的目的是什么?我不是说这是,我只是在问。您是否希望该查询返回几行?如果是这样,那是合法的情况吗?您不想使用WHEN TOO_MANY_ROWS 异常处理程序来处理它(即,而不是使用 ROWNUM 条件)吗?

如果 SELECT 什么都不返回会发生什么?然后它引发NO_DATA_FOUND 异常和触发器失败,当然不会插入任何东西。它是否被传播以使某人(人类)或某物(错误记录程序)看到/捕获它,以便您知道出了什么问题?

当然,事实上 V_ORDER_TYPE 保持为 NULL 会导致 INSERT 失败(正如 P. Salmon 已经建议的那样)。

【讨论】:

  • 可以有多行,但是我只想取回 1 行,因为我只需要 1 个值。我还添加了 NO_DATA_FOUND 异常。但是在这种情况下,数据是存在的,所以它不可能遇到那个异常。
  • 好的,但是 - 哪个“1 行”?如果你不在乎,我猜 ROWNUM 没问题。如果永远不会引发 NO_DATA_FOUND ,则不必处理它(例如,就像测试主键列是否为 NULL - 不能,因为默认情况下主键列不是 NULL )。
  • 我并不关心行,我只是想找出为什么很少有1条记录没有插入到OrderProcessTable中
猜你喜欢
  • 2016-07-23
  • 2021-12-06
  • 2020-04-12
  • 2013-10-12
  • 1970-01-01
  • 1970-01-01
  • 2015-08-17
  • 2018-04-11
  • 2013-10-05
相关资源
最近更新 更多