Проблема на самом деле в том, что вы объявляете локальную переменную и используете ключевое слово DECLARE
. Это запускает новый внутренний блок PL / SQL, но тогда у вас есть OPEN
и т. Д. Без продолжения этого шаблона с новым BEGIN
.
Тем не менее, вам не нужен субблок, просто переместите объявление локальной переменной выше существующего BEGIN
и потеряйте лишние DECLARE
:
CREATE OR REPLACE PROCEDURE IFSAPP.CLEAR_OLD_PURCHASE_ORDERS (cPlannedDelDate in varchar2) IS
-- cursor to get all the purchase orders's that have lines in released state that
CURSOR c1 IS
SELECT DISTINCT PO.ORDER_NO
FROM PURCHASE_ORDER PO, PURCHASE_ORDER_LINE_NOPART POLN
WHERE PO.ORDER_NO = POLN.ORDER_NO
AND POLN.STATE = 'Released'
AND POLN.PLANNED_DELIVERY_DATE < TO_DATE(cPlannedDelDate, 'DD/MM/YYYY');
corder_no varchar2(12);
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO corder_no;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(corder_no);
END LOOP;
CLOSE c1;
END CLEAR_OLD_PURCHASE_ORDERS;
/
Кстати, вы должны рассмотреть возможность использования синтаксиса соединения ANSI, а не древнего синтаксиса с разделителями-запятыми - FROM
. И было бы проще использовать неявный цикл курсора:
CREATE OR REPLACE PROCEDURE IFSAPPCLEAR_OLD_PURCHASE_ORDERS (cPlannedDelDate in varchar2) IS
BEGIN
FOR r1 IN (
SELECT DISTINCT PO.ORDER_NO
FROM PURCHASE_ORDER_LINE_NOPART POLN
JOIN PURCHASE_ORDER PO
ON PO.ORDER_NO = POLN.ORDER_NO
WHERE POLN.STATE = 'Released'
AND POLN.PLANNED_DELIVERY_DATE < TO_DATE(cPlannedDelDate, 'DD/MM/YYYY')
) LOOP
DBMS_OUTPUT.PUT_LINE(r1.order_no);
END LOOP;
END CLEAR_OLD_PURCHASE_ORDERS;
/
Я бы также предпочел, чтобы аргумент процедуры был объявлен как необходимый вам тип данных, то есть как DATE
, так что вы можете использовать его в своем запросе, не конвертируя его; и сделайте так, чтобы вызывающая сторона вставила правильный тип данных в.