Oracle: получение ORA-06550 и PLS-00905 - PullRequest
0 голосов
/ 11 января 2011

у меня есть праздничная таблица, которая содержит данные

    HOLIDAYDA DESCRIPTION
   --------- --------------------
   19-JAN-11 to
   17-JAN-11 to
   10-JAN-11 new day

Теперь я хочу первый рабочий день недели. То есть: если я введу «12-ЯНВ-2011» в качестве ввода, я хочу, чтобы о / п было 11-ЯНВ-2011 в качестве 1-го рабочего дня, потому что 10-ЯНВ-2011 - выходной.

вот мой код:

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

Может кто-нибудь сказать мне причину ошибки? если можно подскажите решение?

Ответы [ 3 ]

8 голосов
/ 11 января 2011

"я скомпилировал вышеупомянутую программу, но с 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 для своихНаша работа.Слишком велика вероятность что-то сломать.Вместо этого создайте новую учетную запись пользователя.

0 голосов
/ 18 января 2011

Помимо уже упомянутых ошибок, попробуйте удалить предложение 'EXIT', поскольку этот цикл будет повторяться фиксированное число раз.Кроме того, попробуйте указать имя блока при завершении блока, как показано ниже:

    LOOP    
    ...
    END LOOP;
END ObjectName;

Где ObjectName - программа верхнего уровня.Здесь это будет «образец», так что:

    LOOP
    ...
    END LOOP;
END sample;
0 голосов
/ 11 января 2011

Я предполагаю, что строка

where holidaydate = l_dStartDay + i);

неверна, поскольку имеет ) там, где ее не должно быть.

...