簡體   English   中英

PL / SQL觸發器從一個表上的INSERT更新另一個表

[英]PL/SQL Trigger to update another table from INSERT on one table

我正在使用SQL和Oracle數據庫,需要一些幫助-觸發器是我很難理解的東西。

當我在表A中插入行時需要一個觸發器,以便它更新表B上的行:特別是其主鍵與剛添加到表A中的行的對應外鍵匹配的行。

因此,例如表A中的X列是一個外鍵,它引用了表B中的Y列(主鍵)。 當我向表AI添加一行時,需要將表B的Z列添加到其中X列= Y列的行中的數字值中。

基於對觸發器的有限理解,這是我到目前為止在SQL上能夠得到的,以防萬一(我意識到它不是很好,請將其視為偽代碼):

CREATE OR REPLACE TRIGGER test_trig
AFTER INSERT OR UPDATE ON tableA
FOR EACH ROW

BEGIN
  UPDATE tableB
  SET columnZ = columnZ + 1
  WHERE tableA.columnX = tableB.columnY;
END test_trig;
/

謝謝

嘗試這個 :

語法將是

CREATE OR REPLACE TRIGGER test_trig
AFTER INSERT OR UPDATE ON tableA
FOR EACH ROW

BEGIN
  UPDATE tableB
  SET columnZ = columnZ + 1
  WHERE tableB.columnX = :NEW.columnX;
END test_trig; 
/

:new.columnX引用表A columnX。

足夠好的開始。

首先-讓我們解決這個問題-標准化不好-您所描述的值似乎應該在運行時而不是在數據處理時計算。

考慮以下:

在列中插入= +1-確定

更新=? 並非總是+1我猜想的列-可能只有在修改某些其他數據時才可以。 例如-如果我更新表set col1 = col1怎么辦? 也許你想要的也許不是。

刪除=? 刪除對列是否意味着-1?

語法:

WHERE tableA.columnX = tableB.columnY;

應該

WHERE :new.columnX = tableB.columnY;

如果tableB.columnZ表示引用的tableA記錄的計數,則除非tableA的引用列可以更改,否則沒有意義觸發tableA的UPDATE。

第一種情況:tableA.ReferenceColumn不變:

CREATE OR REPLACE TRIGGER test_trig
AFTER INSERT ON tableA
FOR EACH ROW
BEGIN

  UPDATE tableB
  SET columnZ = columnZ + 1
  WHERE tableB.columnX = :NEW.columnX;
END test_trig;
/

第二種情況:tableA.ReferenceColumn確實發生了變化:

CREATE OR REPLACE TRIGGER test_trig
AFTER INSERT OR UPDATE OF columnX ON tableA
FOR EACH ROW

BEGIN

  IF UPDATING AND nvl(:OLD.columnX,0) <> 0 THEN
      UPDATE tableB
      SET columnZ = columnZ - 1
      WHERE tableB.columnX = :OLD.columnX;
  END IF:

  IF nvl(:NEW.columnX,0) <> 0 THEN
      UPDATE tableB
      SET columnZ = columnZ + 1
      WHERE tableB.columnX = :NEW.columnX;  
  END IF;

END test_trig;
/

第三種情況:可以刪除tablaA記錄:

CREATE OR REPLACE TRIGGER test_trig
AFTER INSERT OR DELETE OR UPDATE OF columnX ON tableA
FOR EACH ROW

BEGIN
  IF (UPDATING OR DELETING) AND nvl(:OLD.columnX,0) <> 0 THEN
      UPDATE tableB
      SET columnZ = columnZ - 1
      WHERE tableB.columnX = :OLD.columnX;
  END IF:

  IF nvl(:NEW.columnX,0) <> 0 THEN
      UPDATE tableB
      SET columnZ = columnZ + 1
      WHERE tableB.columnX = :NEW.columnX;  
  END IF;
END test_trig;
/

我猜您正在實現某種機制來(A)保持歷史記錄(B)計數器或(C)數據完整性問題。 如果是這種情況,我建議使用可處理所有必要更新/其他DML操作的pl / sql軟件包執行更新。 這是應用程序通過pl / sql軟件包更新數據的最佳實踐。 這樣,您可以在內部控制流程,並且維護起來更加容易。 另外,當您忘記在該表上放置觸發器時,將來可以避免自己的問題。

我可以為您提供一些有關觸發器的提示- 在您決定使用觸發器之前,請確保您已窮盡了所有其他可能性

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM