Oracle

觸發 INSERTING 進入一行

  • December 11, 2021

我正在嘗試創建一個觸發器,該觸發器將在將新學生添加到表中時觸發。它應該通過將其 MCOUNT 域加一來更新名為 MAJOR 的表。

CREATE TABLE STUDENT(
SID     CHAR(7),
SName       VARCHAR2(20),
SMajor      CHAR(3)
CHECK (SMajor in ('CSC', 'MIS', 'TDC')),
CONSTRAINT PK_STUDENT
PRIMARY KEY (SID) 
);



CREATE TABLE MAJOR(
MName       CHAR(3) PRIMARY KEY,
MCount      NUMBER(3) ); 
INSERT INTO MAJOR VALUES ('CSC', 0);
INSERT INTO MAJOR VALUES ('MIS', 0);
INSERT INTO MAJOR VALUES ('TDC', 0);
SELECT * FROM MAJOR;
COMMIT;

我的觸發器:

CREATE OR REPLACE TRIGGER addingS
AFTER INSERT ON STUDENT
   FOR EACH ROW
   DECLARE 
       counter NUMBER (3);
   BEGIN
       DBMS_OUTPUT.PUT_LINE('Adding student.');
       counter := counter + 1;
       UPDATE MAJOR
       SET MCOUNT = counter
       WHERE MCOUNT = 0; 
   END;
   /

它沒有更新,現在我的 MCOUNT 的值是空的,這是為什麼呢?

我認為那counterNULL因為你沒有給它賦值。在你增加它之後,沒有任何變化,因為NULL + 1 = NULL. MCOUNT如果不是 0,您的 UPDATE 也將不起作用。

無關:我建議使用外鍵而不是CHECK.

您定義一個變數,counter。但是,您永遠不會將其設置為一個值,這意味著它的值為 NULL。1 + NULL產生 NULL。

請注意,無論如何,這不會按您的意願工作:

  • 即使您初始化counter為 0,也會為每一行完成。因此,對於每個學生,您將counter設置為 1,並且您將設置MCOUNT為 1,而不是迄今為止擁有該專業的學生人數。
  • 由於您僅設置MCOUNT目前是否為零,因此即使counter設置為具有該專業的學生人數,該UPDATE語句也只會執行一次,並且MCOUNT始終為 1。
  • 最後,您不是在檢查學生SMAJOR,而只是更新該MAJOR專業的記錄。無論MCOUNT一個專業的價值如何,它都適用於所有專業。

幾點注意事項:

  • 您可以使用 的目前值MCOUNT來更新MCOUNT。您確實需要確保MCOUNT永遠不會為 NULL,或者將 NULL 值MCOUNT視為零。
  • 你需要確保你只更新MCOUNT你關心的專業。

就像是

   UPDATE MAJOR
      SET MCOUNT = NVL(MCOUNT, 0) + 1
    WHERE MAJOR = NEW.SMAJOR

應該運作良好。

另外,當然,請注意,如果學生改變了他們的專業,或者如果學生從系統中刪除,您需要處理變化的計數。

引用自:https://dba.stackexchange.com/questions/199616