在触发器中使用更新的项目

时间:2014-11-10 03:14:17

标签: sql database stored-procedures oracle12c

我正在尝试创建一个SQL触发器,用于当Oracle 12c SQL数据库中项目的数量(qoh)低于5.我想从另一个表中选择该项目的描述,并且已经出现使用以下查询,但是当我尝试运行它时出现错误:

/*Creates a trigger to notify someone when an item is out of stock*/
CREATE OR REPLACE TRIGGER ItemOutOfStock
AFTER UPDATE OF INV_QOH ON inventory
FOR EACH ROW
WHEN (new.INV_QOH < 5)
BEGIN
SELECT I.ITEM_DESC
FROM ITEMS I
WHERE I.ITEM_ID = new.ITEM_ID;
END;
/

从我能够弄清楚我应该能够致电new.item_id并且它有效,但事实并非如此。当我更新库存表并使用dbms_output.put_line命令将项目的数量设置为小于5时,它会将文本输出到输出,所以我知道问题出在select语句的某处。

1 个答案:

答案 0 :(得分:0)

SELECT语句必须对数据执行某些操作。您可以将数据存储在触发器中声明的局部变量中。像

这样的东西
CREATE OR REPLACE TRIGGER ItemOutOfStock
  AFTER UPDATE OF INV_QOH ON inventory
  FOR EACH ROW
  WHEN (new.INV_QOH < 5)
DECLARE
  l_item_desc item.item_desc%type;
BEGIN
  SELECT I.ITEM_DESC
    INTO l_item_desc
    FROM ITEMS I
   WHERE I.ITEM_ID = :new.ITEM_ID;

  <<do something with l_item_desc>>
END;
/

请注意,:new伪记录需要以冒号开头。

请注意,从触发器发送电子邮件通常是一个坏主意,因为发送电子邮件是非事务性的。可以触发触发器,但可以回滚事务,以便即使从未提交更新,也可以发送电子邮件。由于写入一致性,触发器也可以多次执行以进行单次更改(在其间进行回滚)。要正确地执行此操作,您确实希望触发器执行某些操作,例如写入一个表,单独的进程定期轮询以发送电子邮件或提交作业(使用dbms_job),如果发送电子邮件和仅当基础事务提交时。