【问题标题】:Oracle SQL Trigger: After Update, Insert Rows into Another TableOracle SQL 触发器:更新后,将行插入另一个表
【发布时间】:2020-04-07 07:54:32
【问题描述】:

我正在尝试在一个表上编写一个触发器,该触发器在库存数量 = 0 时触发。然后它将使用 product_id 和 store_id 在另一个表中添加一行,以指示需要评估该项目以进行重新订购。经过4个多小时的搜索和尝试,我在这里注册了一个帐户。我是新用户,这可能会完全关闭。

这是我最近的尝试:

CREATE OR REPLACE TRIGGER ORDERS_AFTER_UPDATE
AFTER UPDATE 
OF QUANTITY_STOCK 
ON INVENTORY 
FOR EACH ROW
WHEN (NEW.QUANTITY_STOCK - OLD.QUANTITY_STOCK = 0)
BEGIN
SELECT PRODUCT_ID, STORE_ID
INTO PURCHASE_NEW
FROM INVENTORY
WHERE QUANTITY_STOCK = 0;
END;

相关表是 INVENTORY,具有 PRODUCT_ID、STORE_ID,以及 QUANTITY_STOCK 和 PURCHASE_NEW,具有 PRODUCT_ID 和 STORE_ID。我希望它在 QUANTITY_STOCK = 0 的值时将 PRODUCT_ID 和 STORE_ID 从 INVENTORY 表中复制到 PURCHASE_NEW 表中。

我收到的错误是:

Error(8,1): PL/SQL: SQL Statement ignored
Error(9,6): PLS-00403: expression 'PURCHASE_NEW' cannot be used as an INTO-target of a SELECT/FETCH statement
Error(9,19): PL/SQL: ORA-00904: : invalid identifier

非常感谢。

【问题讨论】:

  • SQL 看起来很准。万一,PURCHASE_NEW 可以在另一个数据库或服务器中吗?
  • SELECT ... INTO 是将查询的结果值放入 PL/SQL 变量的 PL/SQL 命令。如果要在表中插入一行,请改用 SQL 的INSERTNEW.QUANTITY_STOCK - OLD.QUANTITY_STOCK = 0NEW.QUANTITY_STOCK = OLD.QUANTITY_STOCK 相同,即没有变化。

标签: sql oracle sql-insert database-trigger


【解决方案1】:

您使用INSERT 将行插入到表中。您可以使用:NEW 访问该行的新值。如果您想知道新的quantity_stock 金额是否为零,请查看:new.quantity_stock = 0。但是,在触发器的 WHEN 子句中,NEW 前面不能有冒号。

CREATE OR REPLACE TRIGGER orders_after_update
AFTER UPDATE OF quantity_stock ON inventory 
FOR EACH ROW
WHEN (new.quantity_stock = 0)
BEGIN
  INSERT INTO purchase_new (product_id, store_id) VALUES (:new.product_id, :new.store_id);
END;

【讨论】:

    【解决方案2】:

    我不确定您为什么要检查 newold quantity_stock 值;只有当您将该值更新为原来的值时,您编写的代码才会触发触发器,因为只有这样它们的差异才会为零。但是,我希望你知道自己在做什么。

    样本数据:

    SQL> create table inventory (product_id number, store_id number, quantity_stock number);
    
    Table created.
    
    SQL> create table purchase_new (product_id number, store_id number);
    
    Table created.
    
    SQL> insert into inventory values (100, 1, 20);
    
    1 row created.
    
    SQL> insert into inventory values (200, 2, 50);
    
    1 row created.
    
    SQL>
    SQL> create or replace trigger orders_after_update
      2    after update of quantity_stock
      3    on inventory
      4    for each row
      5    when (new.quantity_stock - old.quantity_stock = 0)
      6  begin
      7    insert into purchase_new (product_id, store_id)
      8      values (:new.product_id, :new.store_id);
      9  end;
     10  /
    
    Trigger created.
    

    什么都不会发生,因为旧值和新值不同:

    SQL> update inventory set quantity_stock = 15 where product_id = 100;
    
    1 row updated.
    
    SQL> select * From inventory;
    
    PRODUCT_ID   STORE_ID QUANTITY_STOCK
    ---------- ---------- --------------
           100          1             15
           200          2             50
    
    SQL> select * From purchase_new;
    
    no rows selected
    

    但是,如果它们相等,那么触发器会做一些事情:

    SQL> update inventory set quantity_stock = 15 where product_id = 100;
    
    1 row updated.
    
    SQL> select * From inventory;
    
    PRODUCT_ID   STORE_ID QUANTITY_STOCK
    ---------- ---------- --------------
           100          1             15
           200          2             50
    
    SQL> select * From purchase_new;
    
    PRODUCT_ID   STORE_ID
    ---------- ----------
           100          1
    
    SQL>
    

    如果触发线 #5 是

    when (new.quantity_stock = 0)
    

    那么它会更有意义(至少对我来说)。

    【讨论】:

    • 哦,那是我的错。让我删除评论,因为它可能会误导某人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    • 2013-07-01
    • 1970-01-01
    • 2020-08-23
    相关资源
    最近更新 更多