"я скомпилировал вышеупомянутую программу, но с Procedure created with compilation
errors
"
Если вы используете IDE, такую как TOAD или SQL Developer, он автоматически покажет ошибки компиляции.В противном случае они доступны в SQL * Plus с помощью этой команды:
SQL> show errors
Существуют также такие представления, как USER_ERRORS, к которым мы можем обратиться.
Скорее всего, проблема заключается в операторе SELECT, так какПредложение INTO должно следовать сразу после проекции:
select holidaydate
into l_dHolidayDate
from holiday
where holidaydate = l_dStartDay + i);
Имейте в виду, это также выглядит неправильно:
select trunc(to_date(sysdate),'Day')
SYSDATE уже DATE, хотя более поздние версииOracle, как правило, более щадяще использует TO_DATE для столбца 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.Это потому, что ваш поисковый запрос не вернет NULL, когда не найдет подходящую запись, он не будет выполнен.
Это простая процедура.Он использует решение SQL, потому что SQL - самый эффективный способ ведения дел.Внутренний запрос использует трюк CONNECT BY для генерации результирующего набора дат.Затем он уменьшается оператором установки MINUS, который отфильтровывает любые праздники в диапазоне этой недели.Наконец, внешний запрос возвращает самую раннюю дату из запроса.
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 для своихНаша работа.Слишком велика вероятность что-то сломать.Вместо этого создайте новую учетную запись пользователя.