¿Cómo verificar si es un fin de semana en SQL? Sé que puedo convertir sysdate a un número usando esto

 SQL> select to_char(sysdate, 'd') from dual;

 TO_CHAR(SYSDATE,'D')

Pero no estoy muy segura de cómo comprobar si hoy es un 6 o 7.

1
NAlexP 9 sep. 2018 a las 22:16

4 respuestas

La mejor respuesta

No utilice TO_CHAR con el modelo de formato D para esto, ya que depende del parámetro de sesión NLS_TERRITORY.

Por ejemplo, cuando SYSDATE = 2018-09-10 (un lunes):

ALTER SESSION SET NLS_TERRITORY = 'France';
SELECT TO_CHAR( SYSDATE, 'D' ) FROM DUAL;

Salidas 1 pero la misma consulta en un territorio diferente:

ALTER SESSION SET NLS_TERRITORY = 'America';
SELECT TO_CHAR( SYSDATE, 'D' ) FROM DUAL;

Salidas 2.

En su lugar, puede usar TRUNC y el modelo de formato IW:

SELECT TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) FROM DUAL

Emite 0 para el lunes (y 1 para el martes ... 6 para el domingo) y es independiente de la configuración NLS_TERRITORY.

Así que puedes filtrar esto para dar fines de semana como:

SELECT *
FROM   DUAL
WHERE  TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) IN ( 5, 6 )

O

SELECT *
FROM   DUAL
WHERE  SYSDATE - TRUNC( SYSDATE, 'IW' ) >= 5

Si desea que los días indexados en 1 sean coherentes con su salida esperada de TO_CHAR (en lugar de 0 indexados), simplemente agregue 1 al valor.

1
MT0 11 sep. 2018 a las 15:40

sysdate es una pseudo columna. No necesita consultarlo, puede evaluarlo directamente:

IF TO_CHAR(SYSDATE, 'D') IN ('6', '7') THEN
    -- Do something
END IF;
1
Mureinik 9 sep. 2018 a las 19:38

Y aquí está la lógica en una función reutilizable, pero volteó para preguntar "¿Es un día laborable?" (No es un fin de semana). Puede agregar un parámetro para el día de inicio de los días laborables (2 es el valor predeterminado en Oracle; el domingo es el día # 1).

CREATE OR REPLACE FUNCTION is_weekday (date_in IN DATE) 
   RETURN BOOLEAN 
IS 
BEGIN 
   RETURN TO_CHAR (date_in, 'D') BETWEEN 2 AND 6; 
END; 
/

DECLARE 
   l_date   DATE := DATE '2018-09-10'; 
BEGIN 
   DBMS_OUTPUT.put_line ('If your weekend is Saturday and Sunday....'); 

   FOR indx IN 1 .. 7 
   LOOP 
      DBMS_OUTPUT.put_line ( 
            TO_CHAR (l_date, 'FMDay, Month DD YYYY') 
         || ' is ' 
         || CASE WHEN NOT is_weekday (l_date) THEN 'not ' END 
         || 'a weekday'); 
      l_date := l_date + 1; 
   END LOOP; 
END; 
/

Pruébalo en LiveSQL: https://livesql.oracle.com/apex/livesql/fileNconte_SPNG6QSN6SU6PNG1QS_S_PNG1_S_PN_SP_SP_SP_S_PN_A_A_A_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA !! html

0
Steven Feuerstein 9 sep. 2018 a las 23:40

Evitaría el formato ambiguo 'D' ya que esto varía entre territorios (la semana comienza después del fin de semana donde vivo), y uso

if to_char(sysdate,'fmDY','nls_date_language=English') like 'S%'
then

Con respecto al formato 'D', desafortunadamente to_char no le permite especificar nls_territory en línea, por lo que sin un comando explícito alter session, dependerá de la configuración de la sesión en tiempo de ejecución. He visto errores de producción debido a esto, donde el mismo código funcionó en Londres pero falló en Nueva York.

1
William Robertson 10 sep. 2018 a las 04:40