簡體   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