【问题标题】:SQL procedure called from trigger从触发器调用的 SQL 过程
【发布时间】:2016-07-22 17:47:30
【问题描述】:

在 Oracle 环境中(我使用的是 SQLPLUS)。我的问题是如何更改新插入的元组的数据。 这是一个示例:我需要确保每当插入表“Orders”时,如果其属性“weight”大于100,则其另一个属性“size_level”必须为1。否则(weight

CREATE OR REPLACE TRIGGER new_ship_trigger
AFTER INSERT ON Orders
FOR EACH ROW
BEGIN ATOMIC
  CALL UpdateShipSizeLevel(:new)
END;
/

我应该如何编写存储过程部分的代码?或者也许我需要一个光标? 我被要求不要向“订单”表添加约束,并且我应该使用不超过一个触发器。

【问题讨论】:

  • 这是正确的 SQL,只是为了澄清......
  • 1) 通常你可以做一个BEFORE INSERT 触发器,它可以用来在值到达表之前修改或添加值。 2) 此外,size_level派生 信息,通常不应存储(如果可以避免的话)。您可能只能将其定义为视图的一部分。否则,如果您需要性能,请考虑计算列。

标签: sql oracle plsql


【解决方案1】:

您将在这里找到另一个 Oracle 触发器示例。还请务必阅读例如PL/SQL Triggers.

create table so54b (
 id number
,weight number
,weight_level number
);

create or replace trigger so54b_trg
-- note the trigger is also run in update
before insert or update on so54b
for each row
begin
  -- you don't need to implement the trigger logic in a separate
  -- subroutine. however sometimes it might make sense.
  :new.weight_level :=
    case
      when :new.weight > 100 then 1
      else 0
    end;
end;
/
show errors

insert into so54b(id, weight) values (1, 99);
insert into so54b(id, weight) values (2, 100);
-- weight_level is overwritten by the trigger
insert into so54b(id, weight, weight_level) values (3, 101, 13);

select * from so54b order by id;

        ID     WEIGHT WEIGHT_LEVEL
---------- ---------- ------------
         1        99             0
         2       100             0
         3       101             1


update so54b set weight = 80 where weight > 100;

select * from so54b order by id;

        ID     WEIGHT WEIGHT_LEVEL
---------- ---------- ------------
         1         99            0
         2        100            0
         3         80            0

【讨论】:

  • 谢谢。有用。我应该使用 before 而不是 after。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
相关资源
最近更新 更多