触发更新,派生值不起作用

时间:2014-09-10 00:54:47

标签: sql database oracle plsql triggers

我正在编写一个触发器,在更新我的耗材表时进行设置,以更改我的成分表,其中包含用作供应中的外键的主键ingredient_id。成分还包含派生值best_before,其设置为3天+供应中的sup_date。有什么帮助吗?

-------- -----------------------------------------------------------------
8/19     PL/SQL: Statement ignored
8/48     PLS-00357: Table,View Or Sequence reference
     'INGREDIENTS.INGREDIENT_ID' not allowed in this context

17/12    PL/SQL: SQL Statement ignored
18/31    PL/SQL: ORA-00904: "SUPPLIES"."SUP_DATE": invalid identifier
27/14    PL/SQL: Statement ignored
27/80    PLS-00357: Table,View Or Sequence reference
     'INGREDIENTS.INGREDIENT_ID' not allowed in this context
--------------------------------------------------------------

,代码在下面..

CREATE OR REPLACE TRIGGER stock_ing_update

AFTER INSERT OR UPDATE OR DELETE ON supplies
FOR EACH ROW

DECLARE
stock_needed INT;
ing_needed EXCEPTION;
stock_count EXCEPTION;

BEGIN
        IF INSERTING THEN
                  IF :NEW.ing_id = ingredients.ingredient_id THEN
                     UPDATE ingredients  SET stock_amt = 25,
                      best_before = :NEW.sup_date + 3 --correct date derivation??
                      WHERE ingredient_id = :NEW.ing_id; 
              ELSE--IF NOT NEW INGREDIENT
                        INSERT INTO ingredients values(:NEW.ing_id, :NEW.sup_date +3, 25);
              END IF;
    ELSIF UPDATING THEN

       UPDATE ingredients
       SET  best_before = supplies.sup_date + 3
            WHERE ingredient_id = :NEW.ing_id;
    ELSE --DELETING
          RAISE ing_needed;
          RAISE stock_count;

    END IF;
EXCEPTION
        WHEN ing_needed THEN
             DBMS_OUTPUT.PUT_LINE('contact supplier to restock' ||     ingredients.ingredient_id);
        WHEN stock_count THEN
         DBMS_OUTPUT.PUT_LINE('PLEASE RECOUNT STOCK AND UPDATE INGREDIENTS TABLE');

END;
/

及以下是我的加载文件的一部分。

CREATE TABLE ingredients
       (ingredient_id INT PRIMARY KEY,
       best_before DATE NOT NULL,
       stock_amt INT NOT NULL
       );

       INSERT INTO INGREDIENTS VALUES(10011, TO_DATE('13-11-1990', 'DD-MM-YYYY'), 21);


  CREATE TABLE supplies
           (supplier_id INT  REFERENCES supplier(supplier_id),
           ing_id INT REFERENCES ingredients(ingredient_id),
           sup_date DATE NOT NULL,
           PRIMARY KEY(supplier_id, ing_id));

       INSERT INTO supplies VALUES(1001, 10011, TO_DATE('11-11-1990', 'DD-MM-YYYY'));

1 个答案:

答案 0 :(得分:0)

你不能只是在没有阅读表格的情况下引用INGREDIENTS.INGREDIENTS_ID,尽管我们认为你真的不需要。我建议你重写你的触发器:

CREATE OR REPLACE TRIGGER stock_ing_update
  AFTER INSERT OR UPDATE OR DELETE ON supplies
  FOR EACH ROW
DECLARE
  ing_needed   EXCEPTION;
  stock_count  EXCEPTION;
BEGIN
  IF INSERTING THEN
    MERGE INTO INGREDIENTS i
      USING (SELECT :NEW.ING_ID FROM DUAL) d
        ON i.ING_ID = d.ING_ID
      WHEN NOT MATCHED THEN  -- Need to insert a new INGREDIENTS row
        INSERT
          (INGREDIENTS_ID, BEST_BEFORE,       STOCK_AMOUNT)
        values
          (:NEW.ING_ID,    :NEW.SUP_DATE + 3, 25)
      WHEN MATCHED THEN      -- INGREDIENTS row already exists
        UPDATE
          SET STOCK_AMT   = 25,
              BEST_BEFORE = :NEW.SUP_DATE + 3;
  ELSIF UPDATING THEN
    UPDATE ingredients
      SET  best_before = supplies.sup_date + 3
      WHERE ingredient_id = :NEW.ing_id;
  ELSE --DELETING
     RAISE ing_needed;
     RAISE stock_count;  -- Note that once the first exception is raised, the second
  END IF;                -- will not be because the second RAISE will never be executed
EXCEPTION
  WHEN ing_needed THEN
    DBMS_OUTPUT.PUT_LINE('contact supplier to restock' || ingredients.ingredient_id);
    DBMS_OUTPUT.PUT_LINE('PLEASE RECOUNT STOCK AND UPDATE INGREDIENTS TABLE');
END STOCK_ING_UPDATE;

请注意DELETING块中的评论。我留下了两个RAISE调用,但只有 首先将被执行。另请注意,在异常处理程序中,两个WHEN块已合并。

分享并享受。