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