Question

i ont une table de vacances qui contient les données sont

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

Maintenant, je veux que le premier jour ouvrable de la semaine. IE:. Si je passe "12-Jan-2011" en entrée, je veux l'o / p comme 11-Jan-2011 comme le 1er jour ouvrable parce que 10-Jan-2011 est un jour férié

voici mon 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 compilé le programme ci-dessus, mais avec " Procédure créé avec des erreurs de compilation ."

Récemment ajouté: erreurs de Compliation:

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

Erreur :

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

peut me dire la raison de l'erreur? si possible tell me la solution?

Était-ce utile?

La solution

  

"i compilé le programme ci-dessus, mais avec   Procedure created with compilation errors "

Si vous utilisez un IDE tel que TOAD ou SQL Developer il affiche automatiquement les erreurs de compilation. Sinon, ils sont accessibles dans SQL * Plus en utilisant cette commande:

SQL>    show errors

Il y a des vues aussi telles que USER_ERRORS que nous pouvons interroger.

Le problème est très probablement l'instruction SELECT, la clause INTO doit suivre immédiatement après la projection:

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

Rappelez-vous, cela semble aussi mal:

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

SYSDATE est une date déjà, bien que les plus récentes versions d'Oracle ont tendance à être plus indulgent d'utiliser TO_DATE sur une colonne DATE. Lorsque tronquer l'élément de temps à une date il est nécessaire d'inclure un masque de format que c'est le comportement par défaut:

trunc(some_date_variable)

Nous avons seulement besoin d'inclure un masque si (par exemple) nous voulons que le premier jour du mois:

trunc(some_date_variable, 'MON')

Si vous voulez trouver le premier jour de la semaine, ce fera:

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>

Notez que le premier jour de la semaine dépend du réglage du territoire. Dans certains territoires, le premier jour de la semaine est une journée de travail (par exemple lundi au Royaume-Uni) dans d'autres, il n'est pas (le dimanche est le jour 1 aux États-Unis). Ainsi, il peut être nécessaire d'ajouter un décalage.


Une fois que vous résolvez les erreurs de compilation, vous trouverez des erreurs soem exécution, concernant probablement une exception non gérée de NO_DATA_FOUND. Ceci est parce que votre requête de recherche ne retourne pas NULL quand il ne trouve pas un enregistrement correspondant, il échouera.

Ceci est une procédure simple. Il utilise une solution SQL, parce que SQL est la façon la plus efficace de faire les choses. La requête interne utilise le CONNECT BY astuce pour générer un jeu de résultats des dates. Il est ensuite réduit par l'opérateur ensembliste MINUS, qui filtrer les vacances à la plage de cette semaine. Enfin, la requête externe retourne la première date de la requête.

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

Compte tenu de ces données de test (qui reflète l'état des Byzantin jours fériés britanniques) ...

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>

... voici la procédure en action:

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>

Soit dit en passant, ce qui est très mauvaise pratique:

PLS-00905: object SYSTEM.SAMPLE is invalid

Ne pas utiliser le SYS ou SYSTEM intégré dans les comptes pour votre propre travail. Il y a une trop grande chance de casser quelque chose. Créer un nouveau compte utilisateur à la place.

Autres conseils

Je devine que la ligne

where holidaydate = l_dStartDay + i);

est faux car il a un ) où il est pas censé être.

Mis à part les erreurs déjà mentionnées, essayez de supprimer la clause « EXIT » comme cette boucle itérera un nombre fixe de fois. De plus, essayez de spécifier le nom du bloc lors de la fin du bloc comme suit:

    LOOP    
    ...
    END LOOP;
END ObjectName;

Où ObjectName est votre programme de haut niveau. Ici, il serait 'échantillon', donc:

    LOOP
    ...
    END LOOP;
END sample;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top