繁体   English   中英

PL / SQL更新触发器更新所有行

[英]PL/SQL Update Trigger Updates All Rows

使用PL / SQL并尝试创建语句级别触发器的新手,当产品数量(p_qoh)小于产品最小值(p_min)的10或两倍时,该触发器将把'Reorder'值更改为'Yes' 。 如果不是这种情况,则将“重新排序”值更改为“否”。 我的问题是,当我为特定产品执行更新时,它将更改所有行的重新排序值,而不是我指定的行。 似乎无法弄清楚我要去哪里,以为我盯着它看了太久了,对您的帮助将不胜感激。

CREATE OR REPLACE TRIGGER TRG_AlterProd
AFTER INSERT OR UPDATE OF p_qoh, p_min ON product
DECLARE
  v_p_min  product.p_min%type;
  v_p_qoh  product.p_qoh%type;
CURSOR v_cursor IS SELECT p_min, p_qoh FROM product;
BEGIN
  OPEN v_cursor;
LOOP
  FETCH v_cursor INTO v_p_min, v_p_qoh;
  EXIT WHEN v_cursor%NOTFOUND;
IF v_p_qoh < (v_p_min * 2) OR v_p_qoh < 10 THEN
 UPDATE product SET p_reorder = 'Yes';
ELSE
  UPDATE product SET p_reorder = 'No';
END IF;
END LOOP;
END;
/

更新命令:

UPDATE product SET p_reorder = 'Yes';

更新所有行,因为您没有指定WHERE子句。 您可以做的是使用游标检索产品的ID( product_id )并将其保存,以便以这种方式使用它:

UPDATE product SET p_reorder = 'Yes' WHERE id = product_id;

哇,这不是您触发的方式。

1-阅读Oracle触发器文档

2-(几乎)永远不要在触发器中进行提交。 那是调用应用程序的域。

3-无需选择与产品相关的任何内容。 您已经有了带有:new和:old伪记录的产品记录。 只需根据需要更新:new中的列值。 下面的示例(未检查语法错误等);

CREATE OR REPLACE TRIGGER TRG_AlterProd
BEFORE INSERT OR UPDATE OF p_qoh, p_min ON product
FOR EACH ROW
BEGIN

IF :new.p_qoh < (:new.p_min * 2) OR :new.p_qoh < 10 THEN
  :new.p_reorder = 'Yes';
ELSE
  :new p_reorder = 'No';
END IF;
END;

@StevieP,如果需要在触发器内提交,则可能要考虑将其作为“ 自主事务”来进行

另外,如果我对您的问题说明的理解是错误的,对不起,但是您的声音听起来像行级触发器-您是仅更新当前行还是要扫描整个表以更改几行的状态? 如果在当前行上,@ OldProgrammer的解决方案似乎正确。

我只是很好奇,如果您在同一张表的触发器内执行UPDATE语句,它不会生成(递归)触发器吗? 我还没有完成像这样的语句触发器,所以很抱歉,如果这不是预期的触发器行为。

对我来说,语句触发器会更有意义,如果该触发器位于销售表上,则当产品售出(插入到销售表中)时,它将触发要更新的产品ID记录(到REORDER)。 。 那也将防止递归危险。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM