Stored procedures 使用PL/SQL的日期和条件
我在下面的过程中遇到了一个问题,因为每当我传递一个月和年的日期时,IF条件循环表中存在的记录数(只有两行存在),并且它还显示了两种可能性。我还包括了结果,以显示我的意思Stored procedures 使用PL/SQL的日期和条件,stored-procedures,plsql,cursor,Stored Procedures,Plsql,Cursor,我在下面的过程中遇到了一个问题,因为每当我传递一个月和年的日期时,IF条件循环表中存在的记录数(只有两行存在),并且它还显示了两种可能性。我还包括了结果,以显示我的意思 PRODUCT_NUM ORDER_NUM QUANTITY PRICE MONTHLY_DATE -------------- ----------- ------------- ------------ ------------- 12345 106
PRODUCT_NUM ORDER_NUM QUANTITY PRICE MONTHLY_DATE
-------------- ----------- ------------- ------------ -------------
12345 106 3 19.99 21-DEC-15
67894 107 1 19.99 21-DEC-15
CREATE OR REPLACE PROCEDURE Proce_Name (Pram_Date DATE )
AS
BGIN
FOR Y IN
(SELECT SUM(PRICE) AS TOTAL_AMOUNT, SUM(NVL(QUANTITY,0) * NVL (
(PRICE,0)) AS TOTAL, MONTHLY_DATE
FROM PRODUCTS
GROUP BY MONTHLY_DATE
ORDER BY MONTHLY_DATE DESC) LOOP
IF TO_CHAR( Y.MONTHLY_DATE, 'mm-yyyy')= TO_CHAR(Pram_Date,'mm-yyyy') THEN
DBMS_OUTPUT.PUT_LINE('TOTAL AMOUNT: '|| ' '|| Y.TOTAL_AMOUNT);
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('TOTAL: '|| ' '|| Y.TOTAL);
ELSE
DBMS_OUTPUT.PUT_LINE('No Data for this month');
END IF;
END LOOP;
END Proce_name;
调用块:
DECLARE
MONTHLY_D DATE := TO_DATE('01-2012','mm-yyyy');
BEGIN
Proce_Name(MONTHLY_D);
END;
/
此时,我传递的日期与表中的记录匹配:
No Data for this month
TOTAL AMOUNT: 4
TOTAL: 99.96
当我传递一个表中不存在的日期时,这里的结果是:
No Data for this month
No Data for this month
我如何更改我的程序以准确检查上述日期格式
我有如下更新程序
CREATE OR REPLACE PROCEDURE get_sales_report(c_date date) AS
l_amount number(18, 2);
l_total number(18, 2);
BEGIN
begin
SELECT SUM(PRICE), SUM(NVL(QUANTITY, 0) * NVL(PRICE, 0))
into l_amount, l_total
FROM product
where TO_CHAR(MONTHLY_DATE, 'mm-yyyy') = to_char(c_date, 'mm-yyyy')
GROUP BY TO_CHAR(MONTHLY_DATE, 'mm-yyyy')
ORDER BY TO_CHAR(MONTHLY_DATE, 'mm-yyyy') DESC;
DBMS_OUTPUT.PUT_LINE('TOTAL AMOUNT: ' || ' ' || l_amount);
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('TOTAL: ' || ' ' || l_total);
exception
when no_data_found then
DBMS_OUTPUT.PUT_LINE('No Data for this month');
END; -- end of exception
-- add your code here
-- add your code here
-- add your code here
end;
也为dbms_输出回显文本调用以下命令
set serveroutput on size 30000;
将您的过程称为
declare
c_date2 DATE := TO_DATE('12-2015','mm-yyyy');
begin
get_sales_report(c_date2);
end;
这里是代码,您也可以考虑异常处理: 很少观察,你认为PrimulDATE作为字符,而不是通过日期。此外,若数据集很大,且每月的_日期已编制索引,则应避免在每月的_日期应用_char条件
CREATE OR REPLACE PROCEDURE Proce_Name (Pram_Date DATE )
AS
l_total_amount float;
l_total float;
BEGIN
SELECT SUM(PRICE) AS TOTAL_AMOUNT,
SUM(NVL(QUANTITY,0) * NVL(PRICE,0)) AS TOTAL
INTO l_total_amount, l_total
FROM PRODUCTS
WHERE to_char(monthly_date, 'mm-yyyy') = to_char(pram_date, 'mm-yyyy');
if(l_total_amount is not null) then
DBMS_OUTPUT.PUT_LINE('TOTAL AMOUNT: '|| ' '|| L_TOTAL_AMOUNT);
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('TOTAL: '|| ' '|| L_TOTAL);
else
DBMS_OUTPUT.PUT_LINE('No Data for this month');
end if;
END Proce_name;
/
日期是固定大小的类型。所以,如果您想按整个月进行分组,则必须以char形式查询日期列。也就是说,您应该使用TO_CHAR而不是TO_DATE 下面是(更简单的)方法(我的更改是小写)-
这里有一些测试代码-谢谢您的回答,还有保存问题!!您能发布create statement of PRODUCTS表并发布用于调用过程名称过程的代码段吗?请查看问题OK。根据您的测试数据,我建议的代码块应该可以。请注意,;我对select语句、order by和group by进行了更改。你能在运行我的代码块后发布输出吗?这是结果的复制/粘贴-此日期无销售此日期无销售我已对to_char进行了查询,但我需要检查传递到过程的日期。也就是说,如果存在月日,则显示结果。但是,如果该日期不存在,则会显示一条没有本月数据的消息。我不想使用异常,因为这是许多过程中的一个。所以我在同一天有个人的结果!使用EXCEPTION只是更干净的代码,但实际上不必这样做。你可以像以前那样做,用IF-ELSE。尽管如此,还是没有办法避免这种情况。如果您需要将Pram_Date类型设置为Date,那么只需将其作为日期传递,并在您的select中隐式转换它即可。。它看起来像这样-创建或替换过程进程名(Pram_Date)作为开始。。。选择。。。WHERE to_char(每月日期,'mm-yyyy')=to_char(婴儿车日期,'mm-yyyy')…感谢您的回复。你能根据你的评论修改代码吗?完成。因为小提琴坏了,所以无法测试。应该有用。如果是这样,我们将非常感谢您的支持:)谢谢您的回复,该条件在程序中不起作用!而且我有不止一个结果,所以需要循环!
CREATE OR REPLACE PROCEDURE Proce_Name (Pram_Date date) AS
l_month char(7);
l_total_amount number;
l_total number;
BEGIN
SELECT to_char(monthly_date,'mm-yyyy') as month,
SUM(PRICE) AS TOTAL_AMOUNT,
SUM(NVL(QUANTITY,0)*NVL(PRICE,0)) AS TOTAL
INTO l_month, l_total_amount, l_total
FROM PRODUCTS
where to_char(monthly_date,'mm-yyyy')=to_char(Pram_Date, 'mm-yyyy')
GROUP BY to_char(monthly_date,'mm-yyyy');
if l_month is not null then
DBMS_OUTPUT.PUT_LINE('TOTAL AMOUNT: '|| ' '|| Y.TOTAL_AMOUNT);
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('TOTAL: '|| ' '|| Y.TOTAL);
else
DBMS_OUTPUT.PUT_LINE('No Data for this month');
end if;
END Proce_name;
/