【问题标题】:How to use a Function within Anonymous Block?如何在匿名块中使用函数?
【发布时间】:2015-07-20 20:56:03
【问题描述】:

问题

我想使用我创建的函数'calculate_bill_for_order'。我想在我的匿名块中使用它。当我运行匿名块时,应该提示用户输入食品订单号'orderno',然后应该计算食品订单总数。我创建的块不起作用,我不知道为什么。

匿名屏蔽

SET SERVEROUTPUT ON
SET VERIFY OFF
ACCEPT total_order_no PROMPT 'Enter order number to calculate total'
DECLARE
total_order_no varchar2(6) := &total_order_no;
total integer;

BEGIN
  SELECT CALCULATE_BILL_FOR_ORDER(ORDER_CODE) INTO total
  FROM customer_order
  WHERE order_code = total_order_no;

END;
/

功能
效果很好

CREATE OR REPLACE FUNCTION calculate_bill_for_order
    (order_code  IN  customer_order.orderno%TYPE) 
  RETURN number IS
    total_income number := 0;


  CURSOR food_order_cursor  IS
    SELECT dish.price, food_order.n_portions
  FROM food_order, dish
  WHERE food_order.orderno = order_code
  and food_order.dishid = dish.dishid;
  food_record food_order_cursor%ROWTYPE;


  CURSOR drink_order_cursor IS
  SELECT drink.price, drink_order.n_units
  FROM drink, drink_order
  WHERE drink_order.orderno = order_code AND drink_order.drinkid = drink.drinkid;
  drink_record drink_order_cursor%ROWTYPE; 


BEGIN
    OPEN food_order_cursor;
    LOOP
        FETCH food_order_cursor INTO food_record;
        EXIT WHEN food_order_cursor%NOTFOUND;
    total_income := total_income + (food_record.price * food_record.n_portions);
    END LOOP; 
    CLOSE food_order_cursor;


  OPEN drink_order_cursor;
    LOOP
        FETCH drink_order_cursor INTO drink_record;
        EXIT WHEN drink_order_cursor%NOTFOUND;
    total_income := total_income + (drink_record.price * drink_record.n_units);
    END LOOP; 
    CLOSE drink_order_cursor;
    RETURN total_income;
END;
/

更新

您好,感谢您的回复。 这是我得到的错误:

SET SERVEROUTPUT ON
SET VERIFY OFF
ACCEPT total_order_no PROMPT 'Enter order number to calculate total'
DECLARE
total_order_no varchar2(6) := '&total_order_no';
total integer;
BEGIN
  SELECT CALCULATE_BILL_FOR_ORDER(ORDER_CODE) INTO total
  FROM customer_order
  WHERE order_code = total_order_no;

END;
/

Error report -
ORA-06550: line 7, column 9:
PL/SQL: ORA-00904: "ORDER_CODE": invalid identifier
ORA-06550: line 5, column 3:
PL/SQL: SQL Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
Elapsed: 00:00:00.031

**This is your code:**
enter code here
Error report -
ORA-06550: line 2, column 31:
PLS-00201: identifier 'O00001' must be declared
ORA-06550: line 2, column 16:
PL/SQL: Item ignored
ORA-06550: line 4, column 30:
PLS-00302: component 'ORDER_CODE' must be declared
ORA-06550: line 4, column 15:
PL/SQL: Item ignored
ORA-06550: line 13, column 22:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 13, column 22:
PL/SQL: ORA-00904: "TOTAL_ORDER_NO": invalid identifier
ORA-06550: line 11, column 3:
PL/SQL: SQL Statement ignored
ORA-06550: line 15, column 37:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 15, column 3:
PL/SQL: Statement ignored
ORA-06550: line 19, column 47:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 19, column 7:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
Elapsed: 00:00:00.031

**This is your code that I slightly modified:**

SET SERVEROUTPUT ON
SET VERIFY OFF
ACCEPT total_order_no PROMPT 'Enter order number to calculate total'
DECLARE
total_order_no varchar2(6) := &total_order_no;
total number;
v_order_code  customer_order.orderno%type;
BEGIN
  SELECT ORDErno INTO v_order_code
  FROM customer_order
  WHERE orderno = total_order_no AND orderno = order_code;
  total := CALCULATE_BILL_FOR_ORDER(v_order_code);
  EXCEPTION
    WHEN OTHERS THEN
      dbms_output.put_line('No such order' || total_order_no || ' - ' || sqlcode);
END;
/

Orderno is an attribute in Customer_order table AND order_code is a substitution used in calculate_bill_for_order function

【问题讨论】:

  • 定义“不起作用”。你有错误吗?如果是这样,什么错误?您是否看到了您想要或不想要的行为?如果是这样,是什么行为?您没有对在匿名块中计算的total 做任何事情,因此问题可能只是您想做dbms_output.put_line。但是您的问题很可能是其他问题,因为您并不具体。
  • 通常我会在一个简单的选择语句中指定订单号,例如:SELECT DISTINCT calculate_bill_for_order('O00001') as total_bill FROM customer_order;但在匿名块中,我输入 ORDER_CODE 而不是实际代码“O00001”,因为系统会提示用户输入它
  • 您遇到错误了吗?如果是这样,什么错误?您是否看到了您想要或不想要的行为?如果是这样,是什么行为?就像我说的,我的第一个随机猜测是你的匿名块对total 没有任何作用。但是,如果您遇到错误,告诉我们您遇到了什么错误而不是让我们猜测会很有帮助。
  • 嘿,我更新了我的帖子。请看一下

标签: sql plsql oracle11g


【解决方案1】:

您应该发布您遇到的错误,这将有助于我们了解正在发生的事情。 但是,试图弄清楚你在寻找什么,在我看来,这不是执行该操作的正确方法。您可以先获取订单,然后将该订单注入函数,最后您将获得总数。也许这有帮助:

SET SERVEROUTPUT ON
SET VERIFY OFF
ACCEPT total_order_no PROMPT 'Enter order number to calculate total'
DECLARE
total_order_no varchar2(6) := &total_order_no;
total number;
v_order_code  customer_order.order_code%type;

BEGIN
  /*I assumed you are looking for just one value
    and total_order_no is the value to perform the 
    searching of that order number */

  SELECT ORDER_CODE INTO v_order_code
  FROM customer_order
  WHERE order_code = total_order_no;

  total := CALCULATE_BILL_FOR_ORDER(v_order_code);

  EXCEPTION
    WHEN OTHERS THEN
      dbms_output.put_line('No such order' || total_order_no || ' - ' || sqlcode);
END;
/

希望对您有所帮助!!。

【讨论】:

    猜你喜欢
    • 2014-08-16
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 2014-09-11
    • 2022-07-11
    相关资源
    最近更新 更多