Bạn phải chọn kết quả mà hàm trả về thành một cái gì đó . Gì? Ví dụ:một biến cục bộ.
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>
[CHỈNH SỬA] Nếu bạn muốn xóa các ngày tồn tại trong holiday
thì đây là một tùy chọn:sử dụng delete
phương thức thu thập.
Vì bộ sưu tập hiện đang thưa thớt, bạn không thể sử dụng FOR
vòng lặp để hiển thị các giá trị của nó (khi bạn nhận được no_data_found
error) - sử dụng WHILE
thay vào đó.
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.
Xem nó hoạt động:
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>
[CHỈNH SỬA]
Nếu bạn muốn sử dụng NOT EXISTS
, thì đây là cách thực hiện điều đó:
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>