使用PL / SQL并尝试创建一个声明级别触发器,以改变“重新排序”的新功能。价值是'是'当产品数量(p_qoh)小于10或小于产品最小值(p_min)的两倍时。如果情况并非如此,那么就要改变“重新排序”'价值为'否'。我的问题是,当我对特定产品执行更新时,它会更改所有行的重新排序值,而不是我指定的那一行。似乎无法弄清楚我出错的地方,想想我已经盯着它看太久了,非常感谢任何帮助。
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;
/
答案 0 :(得分:2)
更新命令:
UPDATE product SET p_reorder = 'Yes';
更新所有行,因为您没有指定WHERE
子句。
您可以做的是使用光标检索产品的ID( product_id )并保存,以便您可以这样使用它:
UPDATE product SET p_reorder = 'Yes' WHERE id = product_id;
答案 1 :(得分:0)
哇,这不是你怎么做的触发器。
1 - 阅读Oracle Trigger Documentation
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;
答案 2 :(得分:0)
@StevieP,如果你需要在触发器内提交,你可能需要考虑将其作为Autonomous Transaction。
另外,对不起,如果我对您的问题陈述的理解是错误的,但是您的行为听起来像行级触发器 - 您只是更新当前行还是扫描整个表以更改多行的状态?如果它在当前行上,@ OldProgrammer的解决方案似乎是正确的。
我只是好奇,如果你在同一个表的触发器中执行UPDATE语句,它不会生成(递归)触发器吗?我还没有完成这样的语句触发器,如果这不是预期的触发行为,那就很抱歉。
对我来说,一个语句触发器会更有意义,如果触发器在销售表上,当产品被出售(插入销售表)时,它将触发相应的产品ID记录更新(到REORDER)在产品表中。这也可以防止递归危险。