Oracle:ORA-06550およびPLS-00905を受け取ります
質問
データを含むホリデーテーブルがあります
HOLIDAYDA DESCRIPTION
--------- --------------------
19-JAN-11 to
17-JAN-11 to
10-JAN-11 new day
今、私は週の最初の営業日が欲しいです。 IE:「2011年12月12日」を入力として合格した場合、2011年1月10日は休日であるため、O/Pを2011年1月11日1日目にしたいです。
これが私のコードです:
create or replace procedure sample as
l_dStartDay date;
l_dHolidayDate date;
begin
select trunc(to_date(sysdate),'Day')
into l_dStartday
from dual;
dbms_output.put_line('first day of the week ');
dbms_output.put_line(l_dStartDay);
for i in 2..5 Loop
select holidaydate
from holiday
into l_dHolidayDate
where holidaydate = (l_dStartDay + i);
if(l_dHolidaydate is null) then
dbms_output.put_line(l_dStartDay+i);
end if;
exit;
end loop;
end;
上記のプログラムを編集しましたが」コンピレーションエラーで作成された手順."
新しく追加されました:コンプライレンスエラー:
LINE/COL ERROR
-------- -----------------------------------------------------------------
9/1 PL/SQL: SQL Statement ignored
9/33 PL/SQL: ORA-00933: SQL command not properly ended
エラー:
BEGIN sample; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object SYSTEM.SAMPLE is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
エラーの理由を教えてもらえますか?可能であれば、解決策を教えてください。
解決
「上記のプログラムをコンパイルしましたが
Procedure created with compilation errors
"
ToadやSQL開発者などのIDEを使用している場合、コンパイルエラーが自動的に表示されます。それ以外の場合は、このコマンドを使用してSQL*にアクセスできます。
SQL> show errors
また、ユーザー_errorsなどのビューもクエリできます。
問題は、予測の直後に節に従うべきであるため、おそらく選択されたステートメントです。
select holidaydate
into l_dHolidayDate
from holiday
where holidaydate = l_dStartDay + i);
気をつけて、これも間違っているように見えます:
select trunc(to_date(sysdate),'Day')
Sysdateはすでに日付ですが、Oracleの最近のバージョンは、日付列で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 Trickを使用して、日付の結果セットを生成します。これは、マイナスセットオペレーターによって削減され、その週の範囲の休日を除外します。最後に、外部クエリはクエリから最も早い日付を返します。
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またはシステムアカウントを使用しないでください。何かを壊す可能性が大きすぎます。代わりに新しいユーザーアカウントを作成します。
他のヒント
私はそのラインを推測しています
where holidaydate = l_dStartDay + i);
あるので間違っています )
それが想定されていない場所。
既に述べたエラーは別として、このループが固定回数を反復するため、「終了」句を削除してみてください。また、以下のように、ブロックを終了するときにブロック名を指定してみてください。
LOOP
...
END LOOP;
END ObjectName;
ここで、ObjectNameはトップレベルのプログラムです。ここでは、「サンプル」になるので、
LOOP
...
END LOOP;
END sample;