Pregunta

Tengo una tabla de vacaciones que contiene los datos son

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

Ahora quiero que el primer día hábil de la semana. IE:. Si paso "12-ENE-2011" como entrada, quiero que el O / P como el 11-ENE-2011 como el primero día hábil porque el 10-ENE-2011 es día de fiesta

aquí está mi código:

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;

He compilado el programa anterior pero con " Procedimiento creado con errores de compilación ."

acaba de agregar: compliation errores:

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

Error

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

Puede alguien decirme el motivo del error? si es posible Dime la solución?

¿Fue útil?

Solución

"He compilado el programa anterior pero con Procedure created with compilation errors "

Si está utilizando un IDE como SAPO o SQL Developer sería una muestra de los errores de compilación automática. De lo contrario, son accesibles en SQL * Plus usando este comando:

SQL>    show errors

Hay también considera como USER_ERRORS la que podemos consultar.

El problema es más probable que la instrucción SELECT, como la cláusula INTO debe seguir inmediatamente después de la proyección:

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

Eso sí, esto también se ve mal:

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

SYSDATE es una fecha ya, aunque las versiones más recientes de Oracle tienden a ser más tolerantes de utilizar TO_DATE en una columna FECHA. Cuando truncar el elemento de tiempo a partir de una fecha que no es necesario incluir una máscara de formato ya que este es el comportamiento por defecto:

trunc(some_date_variable)

Tan sólo hay que incluir una mascarilla si (por ejemplo) queremos que el primer día del mes:

trunc(some_date_variable, 'MON')

Si usted quiere encontrar el primer día de la semana, esto hará que:

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>

Tenga en cuenta que el primer día de la semana depende de la configuración del territorio. En algunos territorios el primer día de la semana es un día de trabajo (por ejemplo, lunes, en el Reino Unido), en otros no lo es (el domingo es el día 1 en los EE.UU.). Por lo tanto, puede ser necesario añadir un offset.


Una vez que soluciona los errores de compilación se puede encontrar errores de tiempo de ejecución soem, probablemente relacionada con excepciones NO_DATA_FOUND no controladas. Esto se debe a su consulta de búsqueda no devolverá NULL cuando no encuentra un registro coincidente, se producirá un error.

Este es un procedimiento simple. Se utiliza una solución de SQL, ya que SQL es la forma más eficiente de hacer las cosas. La consulta interna utiliza el CONNECT BY truco para generar un conjunto de resultados de las fechas. Esto se reduce a continuación por el operador MINUS, que filtrará a cabo los días festivos en el rango de esa semana. Finalmente la consulta externa devuelve la fecha más temprana de la consulta.

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

Teniendo en cuenta estos datos de prueba (que refleja el estado bizantino de festivos británicos) ...

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>

... aquí está el procedimiento en acción:

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>

Por cierto, esto es muy mala práctica:

PLS-00905: object SYSTEM.SAMPLE is invalid

No utilice la incorporada en el sistema de cuentas SYS o para su propio trabajo. No es demasiado grande la oportunidad de romper algo. Crear una nueva cuenta de usuario en su lugar.

Otros consejos

supongo que la línea

where holidaydate = l_dStartDay + i);

que está mal ya que tiene una ) donde no se supone que sea.

Aparte de los errores ya se ha mencionado, intente eliminar la cláusula 'EXIT' como este bucle se iterar un número fijo de veces. Además, trate de especificar el nombre del bloque al finalizar el bloque como en el siguiente:

    LOOP    
    ...
    END LOOP;
END ObjectName;

Cuando objectname es su programa de nivel superior. En este caso, sería 'muestra', por lo que:

    LOOP
    ...
    END LOOP;
END sample;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top