Oracle:在触发器中使用子查询

时间:2009-05-26 06:20:06

标签: sql oracle triggers subquery

如何解决Oracle在触发器中不允许子查询的限制。

这是我尝试创建的示例触发器,但我无法使用,因为我无法使用子查询。

CREATE OR REPLACE TRIGGER trigger_w_subquery
AFTER UPDATE OR INSERT ON project_archiving
FOR EACH ROW WHEN (old.archiving_status <> new.archiving_status
  AND new.archiving_status = 1
  AND (SELECT offer FROM projects WHERE projnum = :new.projnum) IS NULL
)
BEGIN
  INSERT INTO offer_log (offer, status, date)
  VALUES (null, 9, sysdate);
END;

3 个答案:

答案 0 :(得分:9)

此触发器可以执行此操作:

CREATE OR REPLACE TRIGGER trigger_w_subquery
AFTER UPDATE OR INSERT ON project_archiving
FOR EACH ROW WHEN (old.archiving_status <> new.archiving_status
  AND new.archiving_status = 1
)
DECLARE
  l_offer projects.offer%TYPE;
BEGIN
  SELECT offer INTO l_offer 
  FROM projects 
  WHERE projnum = :new.projnum;

  IF l_offer IS NULL THEN
    INSERT INTO offer_log (offer, status, date)
    VALUES (null, 9, sysdate);
  END IF;
END;

我假设项目中的选择总是会找到一行;如果不是,它将引发您可能需要处理的NO_DATA_FOUND异常。

答案 1 :(得分:5)

我希望你想要像

这样的东西
CREATE OR REPLACE TRIGGER trigger_w_subquery
AFTER UPDATE OR INSERT ON project_archiving
FOR EACH ROW 
WHEN (old.archiving_status <> new.archiving_status
  AND new.archiving_status = 1)
DECLARE
  l_offer projects.offer%TYPE;
BEGIN
  SELECT offer 
    INTO l_offer
    FROM projects 
   WHERE projnum = :new.projnum;

  IF( l_offer IS NULL )
  THEN
    INSERT INTO offer_log (offer, status, date)
      VALUES (null, 9, sysdate);
  END IF;
END;

答案 2 :(得分:2)

你可以把条件放在行动中(在BEGIN和END之间)而不是'是否会发射'吗?是的,这意味着触发器主体可能会更频繁地被触发 - 但是如果它能解决你的问题......