2016-04-03 79 views
0

在Oracle环境(我使用的SQLPLUS)中。我的问题是如何改变新插入的元组的数据。 这里是一个例子:我需要确保插入发生在表“订单”,如果它的属性“weight”大于100,它的另一个属性“size_level”必须是1.否则(重量< = 100), size_level必须为0. 为了做到这一点,我想我需要调用一个存储过程。从触发器调用的SQL过程

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

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

+0

这是SQL正确,只是澄清... – Codexer

+0

@zaggler是的。 – tic30

+5

1)通常你可以做一个'BEFORE INSERT'触发器,它可以用来修改或添加值,然后他们击中表。 2)另外,'size_level'是_derived_信息,通常不应该存储(如果可以避免的话)。您可能只能将其定义为视图的一部分。否则,如果您需要性能,请考虑计算列。 –

回答

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 
+0

谢谢。有用。我应该用之前而不是之后。 – tic30