【问题标题】:Instead of trigger not firing而不是触发器不触发
【发布时间】:2017-10-06 09:49:23
【问题描述】:
  CREATE OR REPLACE PROCEDURE insert_ol
 (
  p_ord_id order_line.order_id%type,
  p_pid order_line.product_id%type,
  p_qty order_line.quantity%type,
  p_price order_line.price%type,
  p_pname order_line.prod_name%type,
  p_alias order_line.prod_alias%type)

  IS
  BEGIN
  INSERT INTO order_line values (p_ord_id, p_pid, p_qty, p_price, p_pname, 
  p_alias);
  END;

我有一个 INSTEAD OF TRIGGER 像这样:

 CREATE OR REPLACE TRIGGER insert_ol
 INSTEAD OF INSERT ON ol_ins
 FOR EACH ROW
 BEGIN
 insert_ol
 (:new.order_id,:new.prod_code,
 :new.qty,prod_cost,:new.prod_name,:new.palias);
 end;

触发器所基于的视图是:

 CREATE OR REPLACE FORCE VIEW "OL_INS"
 AS
 SELECT ot.order_id, prd.prod_code, ot.qty, prd.prod_cost, prd.prod_name, 
 ot.palias 
 FROM ol_temp ot 
 JOIN product prd 
 ON ot.palias=prd.prod_alias;

当我将数据插入“OL_TEMP”表时,部分数据会与“PRODUCT”表连接并进入视图。但触发器不会触发调用过程并将数据插入“ORDER_LINE”表。

我做错了什么以及如何改正?

【问题讨论】:

  • 您的触发器应该使用:new.prod_cost 而不仅仅是prod_cost,但它应该无法编译,并且在您插入视图时会出错。但是您说“当我将数据插入 OL_TEMP` 表时” - 如果您直接操作表,则不会触发针对视图的触发器。插入OL_INS 视图时会发生什么?
  • 我刚刚尝试将数据直接插入视图中,但发生了这种情况:INSERT INTO ol_ins VALUES (4,37, 3, 35,'MINERAL WATER','MW') 命令行错误:1 列:1 错误报告 - SQL 错误:ORA-01779:无法修改映射到非键保留表 01779 的列。00000 -“无法修改映射到非键保留表的列” *原因:尝试是用于插入或更新映射到非键保留表的连接视图的列。 *Action:直接修改底层基表。
  • 还有什么是OL_TEMP,它和其他表有什么关系?
  • Ol_TEMP 只是一个临时表。部分数据通过文本文件进入此表。然后使用视图完成部分数据,然后我使用触发器调用该过程以将完成的数据插入 ORDER_LINE 表。
  • 该错误表明您实际上并未创建触发器。但我敢肯定,根据您所说的,您实际上根本不想要触发器。您期望什么事件导致触发器触发 - 将某些内容插入临时表?

标签: stored-procedures oracle11g triggers


【解决方案1】:

根据

,你似乎把事情倒退了

当我将数据插入“OL_TEMP”表时...

instead of 触发器在您插入 OL_INS 视图时触发,如果您直接操作基础表,它将永远不会触发。所以你应该这样做:

insert into ol_ins (order_id, prod_code, qty, prod_cost, prod_name, palias)
values ( ... )

然后触发器将触发、调用过程并将数据插入到order_line 表中。除非它会出错,因为您的触发器引用 prod_cust(不是已知标识符)而不是 :new.prod_cust

根据您的描述,这根本不是您想要的,并且视图上的触发器没有意义。您似乎想要一个简单的插入,基于您的临时表和永久产品表 - 甚至不清楚您是否需要该视图:

INSERT INTO order_line (order_id, product_id, quantity, price, prod_name, prod_alias)
SELECT ot.order_id, prd.prod_code, ot.qty, prd.prod_cost, prd.prod_name, ot.palias 
FROM ol_temp ot 
JOIN product prd 
ON ot.palias = prd.prod_alias;

如果您确实需要其他视图并想在这里使用它,您仍然可以:

INSERT INTO order_line (order_id, product_id, quantity, price, prod_name, prod_alias)
SELECT order_id, prod_code, qty, prod_cost, prod_name, palias
FROM ol_ins;

但我不会为此创建视图只是。如果你真的想的话,你可以将这些插入中的任何一个包装在一个过程中,但你仍然必须显式调用该过程——而不是从触发器中调用,除非你在临时表上使用了语句后触发器。

【讨论】:

  • 你说得对,我不需要视图。我可以简单地插入 ORDER_LINE 表。所以我要做的是:我在 OL_TEMP 表上添加了一个插入后触发器,以使用部分数据调用过程,并在过程中加入表以插入 ORDER_LINE 表?对吗?
猜你喜欢
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多