在删除前触发器中调用函数

时间:2013-05-03 20:41:12

标签: oracle plsql triggers

id喜欢调用此函数:

CREATE OR REPLACE PACKAGE orders_salary_manage2 AS
  FUNCTION total_calc(p_order in NUMBER)
  RETURN NUMBER;
END;

CREATE OR REPLACE PACKAGE BODY orders_salary_manage2 AS
  tot_orders NUMBER;

FUNCTION total_calc(p_order in NUMBER)
RETURN NUMBER
IS
   c_price product.unit_price%type;
   c_prod_desc product.product_desc%type;
   v_total_cost NUMBER := 0;
   CURSOR c1 IS
      SELECT product_desc, unit_price 
      FROM product 
      WHERE product_id IN (SELECT fk2_product_id 
                           FROM order_line 
                            WHERE fk1_order_id = p_order);
BEGIN
   OPEN c1;
   LOOP
      FETCH c1 into c_prod_desc, c_price;
      v_total_cost := v_total_cost + c_price;
      EXIT WHEN c1%notfound;
   END LOOP;
   CLOSE c1;
   return v_total_cost;
END;

来自此触发器:

CREATE OR REPLACE TRIGGER trg_order_total
BEFORE DELETE ON placed_order 
FOR EACH ROW
DECLARE
v_old_order NUMBER := :old.order_id;
BEGIN
total_calc(v_old_order);
END;

但我一直收到此错误,请注意这里没有错误编号:

第4行出错:PL / SQL:忽略语句

  1. 搁置在搁置订单
  2. 之前
  3. FOR EACH ROW
  4. DECLARE
  5. v_old_order NUMBER:=:old.order_id;
  6. BEGIN
  7. 我是pl / sql的新手,只是不确定导致问题的原因。当用户从订单表中删除订单时,触发器应调用该函数以添加订单上的所有产品。

    谢谢

1 个答案:

答案 0 :(得分:1)

(考虑到你的包编译没有错误)使用 -

ret_val:= orders_salary_manage2.total_calc(v_old_order);

ret_val必须是NUMBER,因为包函数total_calc会返回NUMBER。函数必须始终将其outcoume返回到变量(如ret_val),具体取决于返回值的类型,必须声明变量的数据类型。

调用Pacakaged Procedures和函数的语法是 -

<RETURN_VARIABLE> := PACKAGE_NAME.<FUNCTION_NAME>();
PACKAGE_NAME.<PROCEDURE_NAME>(); --Since Procedure never returns

另请注意,如果您的软件包位于不同的SCHEMA中且没有PUBLIC SYNONYM,那么您必须为<SCHEMA>.PACKAGE_NAME.<FUNCTION_NAME>()之类的模式名称添加前缀(考虑到调用模式对软件包具有执行权限)。

所以,

CREATE OR REPLACE TRIGGER trg_order_total
BEFORE DELETE ON placed_order 
FOR EACH ROW
DECLARE
   v_old_order NUMBER := :old.order_id;
   v_ret_val   NUMBER := 0;
BEGIN
   v_ret_val := orders_salary_manage2.total_calc(v_old_order);
   --...Do stuff with v_ret_val
END;