2011-01-11 8 views
0

ich einen Urlaub Tabelle haben, die die Daten enthalten, istOracle: Empfangen ORA-06550 und PLS-00905

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

Jetzt habe ich die erste Arbeitstag der Woche will. IE: Wenn ich "12-JAN-2011" als Eingabe übergebe, möchte ich die o/p als 11-JAN-2011 als den ersten Werktag, weil 10-JAN-2011 Urlaub ist.

hier ist mein Code: "Verfahren mit Kompilierungsfehlern erstellt"

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

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 mir den Grund für den Fehler sagen? wenn möglich, sag mir die Lösung?

+0

Nun, was sind die Kompilierungsfehler? Natürlich können Sie keine Prozedur aufrufen, die nicht kompiliert wurde. – sjngm

+0

@sjngm: Ich erhielt die Nachricht als "Warnung: Prozedur mit Kompilierungsfehler erstellt.". –

+0

@Rajesh Kumar G: Das hilft niemandem. Was sind die Kompilierungsfehler? Wenn Sie SQL * Plus verwenden, können Sie 'SHOW ERRORS' (oder kurz' SHO ERR') verwenden, um sie zu sehen. – sjngm

Antwort

8

„i das obige Programm zusammengestellt, aber mit Procedure created with compilation errors

Wenn Sie eine IDE wie TOAD oder SQL Developer verwenden, es würde automatisch die Kompilierung-Fehler zeigen. Ansonsten sind sie zugänglich in SQL * Plus mit diesem Befehl:

SQL> show errors 

Es gibt auch Ansichten sind wie USER_ERRORS die wir abfragen.

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') 

SYSDATE ist bereits ein DATE, obwohl die neueren Versionen von Oracle eher tolerant sind, TO_DATE für eine DATE-Spalte zu verwenden.Wenn das Zeitelement von einem Datum Kürzen es nicht notwendig ist, 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 (Sonntag ist Tag 1 in den USA). Daher kann es notwendig sein, einen Offset hinzuzufügen.


Sobald Sie die Kompilierungsfehlern lösen Sie Soem Laufzeitfehler finden, wahrscheinlich nicht behandelte NO_DATA_FOUND Ausnahmen betreffen. Dies liegt daran, dass Ihre Suchabfrage nicht NULL zurückgibt, wenn kein übereinstimmender Datensatz gefunden wird.

Dies ist ein einfaches Verfahren. Es verwendet eine SQL-Lösung, da SQL die effizienteste Methode ist. Die innere Abfrage verwendet den Trick CONNECT BY, um eine Ergebnismenge von Daten zu generieren. Dies wird dann vom MINUS-Set-Operator reduziert, der alle Feiertage in dieser Woche herausfiltert. Schließlich gibt die äußere Abfrage das früheste Datum aus der Abfrage zurück.

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; 
/

diesen Testdaten gegeben (die den byzantinischen Zustand der britischen Feiertage widerspiegelt) ...

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> 

Übrigens ist dies eine sehr schlechte Praxis:

PLS-00905: object SYSTEM.SAMPLE is invalid 

Verwenden Sie nicht die integrierten Konten SYS oder SYSTEM für Ihre eigene Arbeit. Es gibt eine zu große Chance, etwas zu brechen. Erstellen Sie stattdessen ein neues Benutzerkonto.

0

Ich vermute, dass die Linie

where holidaydate = l_dStartDay + i); 

falsch ist, da es ein ) hat, wo es nicht sein sollte.

+0

Tippfehler ist da.Jetzt habe ich den Code geändert. prüfen Sie.Trotzdem erhalte ich denselben Fehler. –

0

Abgesehen von den bereits erwähnten Fehlern versuchen Sie, die 'EXIT' -Klausel zu entfernen, da diese Schleife eine bestimmte Anzahl von Malen durchlaufen wird. Versuchen Sie auch, den Blocknamen anzugeben, wenn Sie den Block wie folgt beenden:

Dabei ist ObjectName Ihr Top-Level-Programm. Hier wäre es "Probe", also:

LOOP 
    ... 
    END LOOP; 
END sample;