Oracle: Empfangen ORA-06550 und PLS-00905
Frage
ich einen Urlaub Tabelle haben, die die Daten enthält, sind
HOLIDAYDA DESCRIPTION
--------- --------------------
19-JAN-11 to
17-JAN-11 to
10-JAN-11 new day
Jetzt möchte ich den ersten Arbeitstag der Woche. IE:. Wenn ich "12-JAN-2011" als Eingabe übergeben, ich möchte, dass die o / p als 11-JAN-2011 als der erste Arbeitstag, weil 10-Jan-2011 ist Urlaub
Hier ist mein Code:
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;
i das obige Programm zusammengestellt, aber mit " Vorgehen erstellt mit Kompilierungsfehlern ."
Neu hinzugefügt: Compliation Fehler:
LINE/COL ERROR
-------- -----------------------------------------------------------------
9/1 PL/SQL: SQL Statement ignored
9/33 PL/SQL: ORA-00933: SQL command not properly ended
Fehler :
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
kann jemand mir sagen, der Grund für den Fehler? wenn möglich, erklären Sie mir die Lösung?
Lösung
"i das obige Programm zusammengestellt, aber mit
Procedure created with compilation errors
"
Wenn Sie eine IDE wie TOAD oder SQL Developer verwenden würde es die Kompilierungsfehlern automatisch angezeigt. Ansonsten sind sie zugänglich in SQL * Plus mit diesem Befehl:
SQL> show errors
Darüber hinaus gibt es wie USER_ERRORS Ansichten, die wir abfragen können.
Das Problem ist höchstwahrscheinlich die SELECT-Anweisung, wie die INTO-Klausel unmittelbar nach der Projektion folgen sollte:
select holidaydate
into l_dHolidayDate
from holiday
where holidaydate = l_dStartDay + i);
Wohlgemerkt, das sieht auch falsch:
select trunc(to_date(sysdate),'Day')
ist SYSDATE ein DATE bereits, obwohl die neueren Versionen von Oracle sind in der Regel mehr zu vergeben, TO_DATE auf einer Datumsspalte zu verwenden. Wenn das Zeitelement von einem Datum Kürzen ist es nicht erforderlich, eine Formatmaske enthalten, da dies das Standardverhalten ist:
trunc(some_date_variable)
Wir brauchen nur eine Maske schließen, wenn (sagen wir) wir den ersten Tag des Monats wollen:
trunc(some_date_variable, 'MON')
Wenn Sie den ersten Tag der Woche finden wollen, das wird es tun:
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>
Beachten Sie, dass der erste Tag der Woche auf dem Gebiet Einstellung abhängt. In einigen Gebieten ist der erste Tag der Woche ein Arbeitstag (zum Beispiel Montag in Großbritannien) in anderen ist es nicht der Fall ist (Sonntag ist Tag 1 in den USA). So kann es notwendig sein eine Offset hinzuzufügen.
Wenn Sie die Kompilierungsfehlern lösen, die Sie Soem Laufzeitfehler finden, wahrscheinlich nicht behandelte NO_DATA_FOUND Ausnahmen beziehen. Dies liegt daran, Ihre Lookup-Abfrage wird nicht NULL zurück, wenn es keinen passenden Datensatz finden, wird es scheitern.
Dies ist ein einfaches Verfahren. Es verwendet eine SQL-Lösung, da SQL die effizienteste Art und Weise, Dinge zu tun ist. Die innere Abfrage verwendet die CONNECT BY Trick eine Ergebnismenge der Daten zu generieren. Dies wird dann durch die MINUS Satz Betreiber reduziert, die keine Feiertage in dieser Woche Bereich herausfiltert. Schließlich wird die äußere Abfrage gibt das früheste Datum aus der Abfrage.
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;
/
Vor diesen Testdaten (die den byzantinischen Zustand der britischen Feiertag widerspiegeln) ...
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>
... hier ist das Verfahren in Aktion:
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>
Das ist übrigens sehr schlechte Praxis:
PLS-00905: object SYSTEM.SAMPLE is invalid
Verwenden Sie nicht den eingebauten in SYS oder SYSTEM-Konten für die eigene Arbeit. Es ist eine zu große Chance, etwas zu brechen. Erstellen Sie ein neues Benutzerkonto statt.
Andere Tipps
Ich nehme an, dass die Zeile
where holidaydate = l_dStartDay + i);
ist falsch, da es eine )
hat, wo es nicht sein sollte.
Neben den Fehler bereits erwähnt, versuchen die ‚EXIT‘ -Klausel, da diese Schleife zu entfernen wird eine feste Anzahl von Malen durchlaufen. Versuchen Sie auch, die Blocknamen angeben, wenn Sie den Blockes wie in den folgenden Endung:
LOOP
...
END LOOP;
END ObjectName;
Wo ObjektName Ihr Top-Level-Programm. Hier wäre es 'Probe', so:
LOOP
...
END LOOP;
END sample;