异常发生时返回OUT参数

时间:2016-01-02 09:53:33

标签: oracle plsql

我有以下程序:

create or replace PROCEDURE FIND_OTHER_DATE (LINE_IDD IN NUMBER,DATE_INN IN VARCHAR2,MMM IN OUT DATE)
AS
BEGIN
   SELECT MAX(INVOICE_DATE) into MMM
   FROM INVOICE
   where INVOICE.LINE_ID=LINE_IDD and INVOICE_DATE <> to_date(DATE_INN,'YYYY-MM-DD HH24:MI:SS') and MONTHS_BETWEEN(to_date(DATE_INN,'YYYY-MM-DD HH24:MI:SS'),INVOICE_DATE)>=1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
    MMM:=to_date('1950-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS');
END;

select语句没有返回任何行时,我希望OUT MMM 参数返回1950-01-01 00:00:00 ..我尝试了上面的代码。但它不起作用,为什么?

1 个答案:

答案 0 :(得分:1)

这不是PL / SQL问题,而是对SQL聚合如何工作的误解。如果没有GROUP BY子句,则保证聚合SELECT语句始终只返回包含MAX()值的一行。

如果您的WHERE子句未返回任何行,MAX()将为NULL。因此,你可以这样写:

SELECT NVL(MAX(INVOICE_DATE), DATE '1950-01-01') 
INTO MMM
FROM INVOICE
WHERE INVOICE.LINE_ID = LINE_IDD 
AND INVOICE_DATE <> to_date(DATE_INN, 'YYYY-MM-DD HH24:MI:SS') 
AND MONTHS_BETWEEN(to_date(DATE_INN, 'YYYY-MM-DD HH24:MI:SS'), INVOICE_DATE) >= 1;

或者,您可以添加GROUP BY (),如果WHERE子句未返回任何行,则不会从聚合返回任何行。在这种情况下,您的NO_DATA_FOUND catch块将适用:

SELECT MAX(INVOICE_DATE)
INTO MMM
FROM INVOICE
WHERE INVOICE.LINE_ID = LINE_IDD 
AND INVOICE_DATE <> to_date(DATE_INN, 'YYYY-MM-DD HH24:MI:SS') 
AND MONTHS_BETWEEN(to_date(DATE_INN, 'YYYY-MM-DD HH24:MI:SS'), INVOICE_DATE) >= 1
GROUP BY ();