创建一个触发器以从另一个表派生列值

时间:2013-08-12 08:54:03

标签: plsql triggers oracle11g

我有两张桌子

Items

ITEM_CODE   VARCHAR2(20)    
ITEM_NAME   VARCHAR2(20)
PRICE_TON   NUMBER(38,5)    
PRICE_REAM  NUMBER(38,5)    
PRICE_SHEET NUMBER(38,5)

Orderitems

ORDER_ITEMS_CODE    VARCHAR2(20)    
ORDER_CODE          VARCHAR2(20)    
ITEM_CODE_ORDERS    VARCHAR2(20)
ORDER_QUANTITY          NUMBER(4,0) 
ORDER_UNIT          VARCHAR2(5)
UNIT_PRICE          NUMBER(38,5)    

我想根据order_unit创建一个触发器来计算unit_price 我尝试了这个触发器,但它不起作用

 create or replace TRIGGER "Orderitems_T1"
    BEFORE
    insert or update on orderitems
    for each row
    begin   
    declare
    order_unit                        orderitems.order_unit%type;
    unit_price                         orderitems.unit_price%type;
    price_sheet                      Items.price_sheet%type;
    price_ream                       Items.price_ream%type;
    price_ton                           Items.price_ton%type;
    item_code                         Items.item_code%type;
    item_code_orders         orderitems.item_code_orders%type;
    when item_code_orders = item_code then
    begin
    case
    when order_unit ='sheet' then  unit_price :=  price_sheet;
    when order_unit = 'ton'  then  unit_price := price_ton ;
    when order_unit = 'ream'  then  unit_price := price_ream ;
    else unit_price  := 0;
    end case;
    end;
    end;

我收到此错误

PLS-00103:遇到以下其中一项时遇到符号“WHEN”:begin function pragma procedure子类型当前游标删除存在

PLS-00103:遇到符号“;”期待以下之一:case符号“case”替换为“;”继续。

2 个答案:

答案 0 :(得分:1)

如前所述,您不能像原先尝试的那样使用WHEN子句,因为您不能在WHEN子句中使用多个表中的字段。看起来您需要从ITEMS中获取与ORDER_ITEMS行上的ORDER_ITEMS_CODE匹配的ITEM_CODE的行,然后将相应的字段从ITEM_CODE行复制到ORDER_ITEMS行。

试试这个:

create or replace TRIGGER Orderitems_T1
  BEFORE insert or update on orderitems
  for each row
declare
  rowItems  ITEMS%ROWTYPE;
begin
  SELECT *
    INTO rowItems
    FROM ITEMS i
    WHERE i.ITEM_CODE = :NEW.ORDER_ITEMS_CODE;

  case
    when :NEW.order_unit = 'sheet' then
      :NEW.unit_price := rowItems.price_sheet;
    when :NEW.order_unit = 'ton' then
      :NEW.unit_price := rowItems.price_ton ;
    when :NEW.order_unit = 'ream' then
      :NEW.unit_price := rowItems.price_ream ;
    else
      :NEW.unit_price := 0;
  end case;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('No row found in ITEMS for ' ||
                         'ORDERITEMS.ORDER_ITEMS_CODE=''' ||
                         :NEW.ORDER_ITEMS_CODE || '''');
    RAISE;  -- re-raise the error if an invalid item code is found
end Orderitems_T1;

分享并享受。

答案 1 :(得分:0)

有一些语法错误 您能否尝试运行以下代码

create or replace TRIGGER "Orderitems_T1"
BEFORE
insert or update on orderitems
for each row
when (item_code_orders = item_code )
--begin   --remove this begin
AS
order_unit                        orderitems.order_unit%type;
unit_price                         orderitems.unit_price%type;
price_sheet                      Items.price_sheet%type;
price_ream                       Items.price_ream%type;
price_ton                           Items.price_ton%type;
item_code                         Items.item_code%type;
item_code_orders         orderitems.item_code_orders%type;

begin
case
when order_unit ='sheet' then  unit_price :=  price_sheet;
when order_unit = 'ton'  then  unit_price := price_ton ;
when order_unit = 'ream'  then  unit_price := price_ream ;
else order_unit := 0;
end case;
end;