销售报告pl / sql

时间:2015-12-12 19:59:47

标签: oracle plsql

我正在尝试创建一个生成任何给定月份的销售报告的程序。要调用该过程,我只能传递一个月份的参数来获得销售数量以及总销售额。我加入了三个表格:订单,尾部和部分,如下面的选择查询中所示。我的问题是我创建的程序在我将日期传递给它时没有生成任何记录!你能告诉我如何改变吗?

create or replace PROCEDURE SALE_REPORT (P_DATE IN DATE ) 
   AS
V_PNO ODETAILS.PNO%TYPE;
NUMBER_SALES ODETAILS.QTY%TYPE;
TOTAL_SALE  PARTS.PRICE%TYPE;
V_SHIPPED ORDERS.SHIPPED%TYPE;
BEGIN
 DBMS_OUTPUT.PUT_LINE('           REPORT          ');
 DBMS_OUTPUT.PUT_LINE('*****************************');
  FOR REC IN 
  (SELECT OD.PNO, SUM(OD.QTY) "NUMBER OF SALES", SUM(NVL(OD.QTY,0) * NVL  
                                   (P.PRICE,0)) AS TOTAL_SALE, O.SHIPPED 
  INTO V_PNO, NUMBER_SALES, TOTAL_SALE, V_SHIPPED 
  FROM ORDERS O, ODETAILS OD, PARTS P
  WHERE O.ONO = OD.ONO
  AND P.PNO = OD.PNO
  AND O.SHIPPED = TO_CHAR(P_DATE, 'DD-MON-yyyy')
  GROUP BY  O.SHIPPED, OD.PNO
  ORDER BY SUM(OD.QTY) DESC) LOOP

  DBMS_OUTPUT.PUT_LINE('SHIP DATE '||  V_PNO);
  DBMS_OUTPUT.PUT_LINE('SHIP DATE '|| V_SHIPPED);
  DBMS_OUTPUT.PUT_LINE('NUMBER OF SALES '|| NUMBER_SALES);
  DBMS_OUTPUT.PUT_LINE('TOTAL SALES '|| TOTAL_SALE );
  EXIT WHEN SQL%NOTFOUND;
   END LOOP;
END SALE_REPORT;

1 个答案:

答案 0 :(得分:1)

首先,你的语法。

如果您正在使用FOR循环,则不需要SELECT ... INTO构造,使用您声明的REC变量 - 实际上,我甚至对这甚至编译感到惊讶。 EXIT WHEN SQL%NOTFOUND;也是不必要的,因为FOR循环自动结束,没有更多记录。另外,为列提供更好的别名,您将使用它们作为REC的成员。

它应该是这样的:

FOR REC IN 
  (SELECT OD.PNO, SUM(OD.QTY) NUMBER_SALES, SUM(NVL(OD.QTY,0) * NVL  
                                   (P.PRICE,0)) AS TOTAL_SALE, O.SHIPPED 
  FROM ORDERS O, ODETAILS OD, PARTS P
  WHERE O.ONO = OD.ONO
  AND P.PNO = OD.PNO
  AND O.SHIPPED = TO_CHAR(P_DATE, 'DD-MON-yyyy')
  GROUP BY  O.SHIPPED, OD.PNO
  ORDER BY SUM(OD.QTY) DESC) LOOP

  DBMS_OUTPUT.PUT_LINE('SHIP DATE '||  REC.PNO);
  DBMS_OUTPUT.PUT_LINE('SHIP DATE '|| REC.SHIPPED);
  DBMS_OUTPUT.PUT_LINE('NUMBER OF SALES '|| REC.NUMBER_SALES);
  DBMS_OUTPUT.PUT_LINE('TOTAL SALES '|| REC.TOTAL_SALE );
END LOOP;

我也会将此查询转换为游标并移至声明,但我猜这是偏好。

现在,如果仍然没有打印任何内容,那么您的查询不会返回任何行。将其带到SQL工作表,手动替换P_DATE并进行调试。

修改

如果o.shipped是月内的任何日期,并且您将日期作为01-12-2015传递,那么您的查询将仅返回o.shipped与您的{P_DATE完全匹配的行1}},也就是一个月的第一天。您应该将日期转换为包含月份和年份的字符串:

...
AND TO_CHAR(O.SHIPPED, 'mm.yyyy') = TO_CHAR(P_DATE, 'mm.yyyy')
...

或使用TRUNC函数和第二个参数MONTH,这会将您的日期转换为每月的第一天。

...
AND TRUNC(O.SHIPPED, 'MONTH') = TRUNC(P_DATE, 'MONTH')
...