Musisz wybrać wynik, który funkcja zwraca do czegoś . Co? Na przykład zmienna lokalna.
SQL> CREATE OR REPLACE PROCEDURE date_test (start_date DATE, end_date DATE)
2 IS
3 l_res nt_Date;
4 BEGIN
5 SELECT generate_dates_pipelined (start_date, end_date)
6 INTO l_res
7 FROM DUAL;
8
9 FOR i IN l_res.FIRST .. l_res.LAST
10 LOOP
11 DBMS_OUTPUT.put_line (l_res (i).date_val);
12 END LOOP;
13 END;
14 /
Procedure created.
SQL> set serveroutput on
SQL> EXEC date_test(DATE '2021-08-01', DATE '2021-08-10');
01.08.21
02.08.21
03.08.21
04.08.21
05.08.21
06.08.21
07.08.21
08.08.21
09.08.21
10.08.21
PL/SQL procedure successfully completed.
SQL>
[EDYTUJ] Jeśli chcesz usunąć daty, które istnieją w holiday
tabeli, to jest jedna opcja:użyj delete
metoda zbierania.
Ponieważ kolekcja jest teraz rzadka, nie możesz użyć FOR
pętla, aby wyświetlić jej wartości (jak otrzymasz no_data_found
błąd) - użyj WHILE
zamiast tego.
SQL> CREATE OR REPLACE PROCEDURE date_test (start_date DATE, end_date DATE)
2 IS
3 l_res nt_date;
4 i NUMBER;
5 l_cnt NUMBER;
6 BEGIN
7 SELECT generate_dates_pipelined (start_date, end_date)
8 INTO l_res
9 FROM DUAL;
10
11 DBMS_OUTPUT.put_line ('contents of L_RES (all dates) ------------');
12
13 FOR i IN l_res.FIRST .. l_res.LAST
14 LOOP
15 DBMS_OUTPUT.put_line (l_res (i).date_val);
16 END LOOP;
17
18 DBMS_OUTPUT.put_line ('removing holidays -------------------------');
19
20 FOR i IN l_res.FIRST .. l_res.LAST
21 LOOP
22 SELECT MAX (1)
23 INTO l_cnt
24 FROM holidays
25 WHERE holiday_date = l_res (i).date_val;
26
27 DBMS_OUTPUT.put_line (
28 l_res (i).date_val || ': cnt = ' || l_cnt || ' - delete it!');
29
30 IF l_cnt = 1
31 THEN
32 l_res.delete (i);
33 END IF;
34 END LOOP;
35
36 DBMS_OUTPUT.put_line ('contents of L_RES (holidays excluded) ----');
37
38 i := l_res.FIRST;
39
40 WHILE i IS NOT NULL
41 LOOP
42 DBMS_OUTPUT.put_line (l_res (i).date_val);
43 i := l_res.NEXT (i);
44 END LOOP;
45 END;
46 /
Procedure created.
Zobacz, jak działa:
SQL> SELECT * FROM holidays;
HOLIDAY_DA HOLIDAY_NAME
---------- --------------------
01.08.2021 August 01 2021
05.08.2021 August 05 2021
SQL> EXEC date_test(date '2021-08-01', date '2021-08-10');
contents of L_RES (all dates) ------------
01.08.2021
02.08.2021
03.08.2021
04.08.2021
05.08.2021
06.08.2021
07.08.2021
08.08.2021
09.08.2021
10.08.2021
removing holidays -------------------------
01.08.2021: cnt = 1 - delete it!
02.08.2021: cnt = - delete it!
03.08.2021: cnt = - delete it!
04.08.2021: cnt = - delete it!
05.08.2021: cnt = 1 - delete it!
06.08.2021: cnt = - delete it!
07.08.2021: cnt = - delete it!
08.08.2021: cnt = - delete it!
09.08.2021: cnt = - delete it!
10.08.2021: cnt = - delete it!
contents of L_RES (holidays excluded) ----
02.08.2021
03.08.2021
04.08.2021
06.08.2021
07.08.2021
08.08.2021
09.08.2021
10.08.2021
PL/SQL procedure successfully completed.
SQL>
[EDYTUJ]
Jeśli chcesz użyć NOT EXISTS
, oto jak to zrobić:
SQL> SELECT date_val
2 FROM TABLE (
3 generate_dates_pipelined (DATE '2021-08-01', DATE '2021-08-10'))
4 WHERE NOT EXISTS
5 (SELECT 1
6 FROM holidays h
7 WHERE date_val = h.holiday_date);
DATE_VAL
----------
02.08.2021
03.08.2021
04.08.2021
06.08.2021
07.08.2021
08.08.2021
09.08.2021
10.08.2021
8 rows selected.
SQL>