Domanda

Ho una tabella di vacanza che contiene i dati sono

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

Ora voglio il primo giorno lavorativo della settimana. IE:. Se passo "12-Gen-2011" come input, voglio l'O / P da 11-GEN-2011 come il giorno prima business perché 10-Gen-2011 è festa

Ecco il mio codice:

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;

ho compilato il programma di cui sopra, ma con " Procedura creato con errori di compilazione ".

Nuovo Aggiunti: errori compliation:

 LINE/COL ERROR
 -------- -----------------------------------------------------------------
 9/1      PL/SQL: SQL Statement ignored
 9/33     PL/SQL: ORA-00933: SQL command not properly ended

Errore :

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

uno può dirmi il motivo per l'errore? se possibile, tell me la soluzione?

È stato utile?

Soluzione

  

"ho compilato il programma di cui sopra, ma con   Procedure created with compilation errors "

Se si utilizza un IDE come TOAD o SQL Developer sarebbe mostrare gli errori di compilazione automatica. In caso contrario, essi sono accessibili in SQL * Plus utilizzando questo comando:

SQL>    show errors

Ci sono viste anche come USER_ERRORS cui possiamo interrogare.

Il problema è più probabile che l'istruzione SELECT, come la clausola INTO dovrebbe seguire subito dopo la proiezione:

   select holidaydate 
     into l_dHolidayDate 
     from holiday 
    where holidaydate = l_dStartDay + i);

Intendiamoci, questo sembra anche sbagliato:

select trunc(to_date(sysdate),'Day') 

SYSDATE è già una data, anche se le versioni più recenti di Oracle tendono ad essere più indulgente di utilizzare TO_DATE su una colonna DATE. Quando troncando l'elemento tempo da una data non è necessario includere una maschera di formato come questo è il comportamento di default:

trunc(some_date_variable)

Abbiamo solo bisogno di includere una maschera, se (ad esempio) vogliamo il primo giorno del mese:

trunc(some_date_variable, 'MON')

Se si vuole trovare il primo giorno della settimana, questo lo farà:

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>

Si noti che il primo giorno della settimana dipende dalla impostazione territorio. In alcuni territori il primo giorno della settimana è un giorno lavorativo (per esempio Lunedi nel Regno Unito), in altri non è (Domenica è il giorno 1 negli Stati Uniti). Così può essere necessario aggiungere un offset.


Una volta a risolvere gli errori di compilazione troverete soem runtime errori, probabilmente in materia di eccezioni non gestite NO_DATA_FOUND. Questo perché la query di ricerca non restituirà NULL quando non trova un record corrispondente, fallirà.

Questa è una procedura semplice. Si utilizza una soluzione SQL, SQL, perché è il modo più efficiente di fare le cose. La query interna utilizza il CONNECT BY trucco per generare un set di risultati di date. Questo viene poi ridotta dall'operatore insieme MINUS, che filtrerà eventuali vacanze nella gamma di quella settimana. Infine, la query esterna restituisce la prima data dalla query.

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

Dato questo dati di test (che riflette lo stato bizantina di giorni festivi britannici) ...

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>

... ecco la procedura in azione:

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>

Per inciso, questo è molto cattiva pratica:

PLS-00905: object SYSTEM.SAMPLE is invalid

Non utilizzare il built-in SYS o sistema contabile per il proprio lavoro. Non è troppo grande la possibilità di rompere qualcosa. Creare un nuovo account utente, invece.

Altri suggerimenti

Sto indovinando che la linea

where holidaydate = l_dStartDay + i);

è sbagliato in quanto ha una ) dove non dovrebbe essere.

A parte gli errori già accennato, provare a rimuovere la clausola 'EXIT' come questo ciclo sarà iterare un numero fisso di volte. Inoltre, provare a specificare il nome del blocco in cui termina il blocco come di seguito:

    LOOP    
    ...
    END LOOP;
END ObjectName;

Dove NomeOggetto è il tuo programma di alto livello. Qui, sarebbe 'campione', così:

    LOOP
    ...
    END LOOP;
END sample;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top