【问题标题】:Calling a function in a before delete trigger在删除前触发器中调用函数
【发布时间】:2013-05-03 20:41:12
【问题描述】:

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. 声明
  4. v_old_order NUMBER := :old.order_id;
  5. 开始

我是 pl/sql 的新手,只是不确定是什么导致了问题。当用户从订单表中删除订单时,触发器应调用该函数以将订单上的所有产品相加。

谢谢

【问题讨论】:

  • 您显示的触发代码根本没有调用add_order_func 函数。你的意思是你从当前的触发代码中得到那个错误,或者当你试图改变它来调用函数时你得到那个错误?如果是前者,那么问题可能出在您正在调用的total_calc 过程上。如果是后者,则显示实际尝试调用该函数的触发代码。
  • 您好,感谢您的回复,对不起,我显示错误的功能,我已经工作了几个小时,我的大脑正在关闭。我基本上是在尝试在发生删除时执行函数,并且传递给函数的参数应该是行的 order_id (PK)
  • 我们错过了实际的错误描述(ORA-XXXXX: bla bla bla..)

标签: oracle plsql triggers


【解决方案1】:

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

ret_val:= orders_salary_manage2.total_calc(v_old_order);

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

调用封装过程和函数的语法是-

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

另请注意,如果您的包位于不同的 SCHEMA 中并且没有 PUBLIC SYNONYM,那么您必须在架构名称前加上 &lt;SCHEMA&gt;.PACKAGE_NAME.&lt;FUNCTION_NAME&gt;() 之类的前缀(考虑到调用架构对包具有执行权限)。

所以,

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;

【讨论】:

  • 嗨,annjawn,我昨晚设法弄清楚并想出了这个:在删除每行放置的订单之前创建或替换触发器 trg_order_total 声明 v_old_order NUMBER := :old.order_id; v_total NUMBER;开始 v_total := total_calc(v_old_order);从 order_line 中删除 fk1_order_id = v_old_order ; dbms_output.put_line(v_total);结尾;不过还是谢谢你的回复!你的权利我需要将函数的结果存储在一个变量中!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-12
  • 2021-02-01
相关资源
最近更新 更多