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?

War es hilfreich?

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;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top