sql >> データベース >  >> RDS >> Oracle

関数を呼び出すOracle作成プロシージャ

    関数が何かに返す結果を選択する必要があります 。何?たとえば、ローカル変数。

    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>
    

    [編集] holidayに存在する日付を削除する場合 テーブルの場合、これは1つのオプションです。deleteを使用します 収集方法。

    コレクションがまばらになっているため、FORを使用することはできません ループしてその値を表示します(no_data_foundを取得するように) エラー)-WHILEを使用します 代わりに。

    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.
    

    動作することを確認してください:

    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>
    

    [編集]

    NOT EXISTSを使用したい場合 、それからこれはそれを行う方法です:

    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>
    



    1. ODCIEXTTABLEOPENコールアウトの実行中にエラーが発生しました

    2. MySQLはWHERE句を使用してINSERTINTOを直接挿入します

    3. SQL複数の関係が存在する行のみを選択します

    4. PostgreSQLは部分インデックスを使用しません