「私は上記のプログラムをコンパイルしましたが、
Procedure created with compilation
errors
」
TOADやSQLDeveloperなどのIDEを使用している場合は、コンパイルエラーが自動的に表示されます。それ以外の場合は、次のコマンドを使用してSQL*Plusでアクセスできます。
SQL> show errors
クエリできるUSER_ERRORSなどのビューもあります。
INTO句は射影の直後に続く必要があるため、問題はおそらくSELECTステートメントです。
select holidaydate
into l_dHolidayDate
from holiday
where holidaydate = l_dStartDay + i);
気をつけてください、これも間違っているように見えます:
select trunc(to_date(sysdate),'Day')
SYSDATEはすでにDATEですが、Oracleの最近のバージョンでは、DATE列でTO_DATEを使用することをより許容する傾向があります。日付から時間要素を切り捨てる場合、これがデフォルトの動作であるため、フォーマットマスクを含める必要はありません。
trunc(some_date_variable)
(たとえば)月の最初の日が必要な場合にのみ、マスクを含める必要があります。
trunc(some_date_variable, 'MON')
週の最初の日を見つけたい場合は、次のようにします。
SQL> select
2 trunc(to_date('01-DEC-2010', 'DD-MON-YYYY'), 'D') start_of_wk
3 from dual
4 /
START_OF_
---------
29-NOV-10
SQL>
週の最初の日は地域の設定によって異なることに注意してください。一部の地域では、週の最初の日が稼働日(たとえば、英国では月曜日)であり、そうでない地域(米国では日曜日は1日目)です。したがって、オフセットを追加する必要がある場合があります。
コンパイルエラーを解決すると、おそらく未処理のNO_DATA_FOUND例外に関連するsoemランタイムエラーが見つかります。これは、一致するレコードが見つからない場合、ルックアップクエリがNULLを返さないため、失敗します。
これは簡単な手順です。SQLは物事を行うための最も効率的な方法であるため、SQLソリューションを使用します。内部クエリは、CONNECT BYトリックを使用して、日付の結果セットを生成します。次に、これはMINUS set演算子によって削減され、その週の範囲内のすべての休日が除外されます。最後に、外部クエリはクエリから最も早い日付を返します。
create or replace procedure get_first_working_day
( p_tgt_date in date )
is
l_st_day date := trunc(p_tgt_date, 'D');
l_working_day date := trunc(p_tgt_date, 'D');
begin
dbms_output.put_line('first day of week = '||l_st_day);
select min(day_of_wk)
into l_working_day
from ( select l_st_day + (level-1) as day_of_wk
from dual
connect by level <= 5
minus
select holidaydate
from hols
where holidaydate between l_st_day and l_st_day + 4 );
dbms_output.put_line('first working day of week = '||l_working_day
||'::'|| to_char(l_working_day, 'DAY'));
end get_first_working_day;
/
このテストデータ(英国の銀行の休日のビザンチン状態を反映している)を考えると...
SQL> select holidate from hols
2 order by 1
3 /
HOLIDAYDA
---------
25-DEC-10
26-DEC-10
27-DEC-10
28-DEC-10
01-JAN-11
03-JAN-11
6 rows selected.
SQL>
...実際の手順は次のとおりです。
SQL> set serveroutput on size unlimited
SQL>
SQL> exec get_first_working_day (sysdate)
first day of week = 10-JAN-11
first working day of week = 10-JAN-11::MONDAY
PL/SQL procedure successfully completed.
SQL>
SQL> exec get_first_working_day (to_date( '04-JAN-2011', 'DD-MON-YYYY'))
first day of week = 03-JAN-11
first working day of week = 04-JAN-11::TUESDAY
PL/SQL procedure successfully completed.
SQL>
SQL> exec get_first_working_day (to_date( '01-JAN-2011', 'DD-MON-YYYY'))
first day of week = 27-DEC-10
first working day of week = 29-DEC-10::WEDNESDAY
PL/SQL procedure successfully completed.
SQL>
ちなみに、これは非常に悪い習慣です。
PLS-00905: object SYSTEM.SAMPLE is invalid
組み込みのSYSまたはSYSTEMアカウントを自分の作業に使用しないでください。何かを壊す可能性が高すぎます。代わりに、新しいユーザーアカウントを作成してください。