Objetivos:
•Ver el uso de algunas funciones de fecha en PL/SQL, para con ellas crear una(función, trigger, procedimiento...) que cumpla cierto requerimiento .
•Mas que nada, entretenerme un poco.
Con frecuencia vemos programas/software que determinan el tiempo que falta para tu próximo cumpleaños, algunos te dan hasta detalles como: las horas, minutos y segundos que restan, así como también el tiempo que has vivido en días, horas o minutos. A mi me paso por la mente realizar algo parecido(con días), pero en PL/SQL.
Nota: No doy muchas explicaciones ya que las funciones que uso están explicadas en publicaciones anteriores.
Por defecto la base de datos ORACLE muestra las fechas en formato: 'DD-MM-RR HH:MI:SS' pero esto puede cambiarse con ALTER SESSION SET NLS_DATE_FORMAT='MM/DD/YYYY';
Para lograr que el siguiente SCRIPT tenga los resultados esperados, el formato de NLS_DATE_FORMAT debe estar en este orden: DD/MM/YYYY o DD-MM-YYYY.
Para ver el actual formato de tu session usa: SELECT parameter, value FROM nls_session_parameters;
CREATE OR REPLACE FUNCTION DAYS_TO_BIRTHDAY(P_UR_BIRTH IN VARCHAR2) RETURN VARCHAR2 AS --Declaro P_UR_BIRTH VARCHAR2 para así poder mostrar errores si no introducen una fecha validad... CURSOR C_DAY_THIS_YEAR(P_DATE IN DATE) IS SELECT TO_DATE(EXTRACT(DAY FROM P_DATE) ||'/'||EXTRACT(MONTH FROM P_DATE) ||'/'||EXTRACT(YEAR FROM SYSDATE),'DD/MM/YYYY')-TRUNC(SYSDATE) FROM DUAL; CURSOR C_DAY_NEXT_YEAR(P_DATE IN DATE) IS SELECT TO_DATE(EXTRACT(DAY FROM P_DATE) ||'/'||EXTRACT(MONTH FROM P_DATE) ||'/'||EXTRACT(YEAR FROM ADD_MONTHS(SYSDATE,12)),'DD/MM/YYYY')-TRUNC(SYSDATE) FROM DUAL; V_MONTH NUMBER(2); V_DAY V_MONTH%TYPE; V_DAYS NUMBER(3); V_UR_BIRTH DATE; BEGIN V_UR_BIRTH := TO_DATE(P_UR_BIRTH,'DD/MM/YYYY'); V_MONTH := EXTRACT(MONTH FROM V_UR_BIRTH); V_DAY := EXTRACT(DAY FROM V_UR_BIRTH); IF V_MONTH > EXTRACT(MONTH FROM SYSDATE) THEN OPEN C_DAY_THIS_YEAR(V_UR_BIRTH); FETCH C_DAY_THIS_YEAR INTO V_DAYS; CLOSE C_DAY_THIS_YEAR; RETURN 'Faltan '||V_DAYS||' Días para tu cumpleaños'; ELSIF V_MONTH = EXTRACT(MONTH FROM SYSDATE) THEN IF V_DAY > EXTRACT(DAY FROM SYSDATE) THEN OPEN C_DAY_THIS_YEAR(V_UR_BIRTH); FETCH C_DAY_THIS_YEAR INTO V_DAYS; CLOSE C_DAY_THIS_YEAR; RETURN 'Faltan '||V_DAYS||' Días para tu cumpleaños'; ELSIF V_DAY = EXTRACT(DAY FROM SYSDATE) THEN RETURN '!_$_!Happy Birth Day to You!_$_!'; ELSE OPEN C_DAY_NEXT_YEAR(V_UR_BIRTH); FETCH C_DAY_NEXT_YEAR INTO V_DAYS; CLOSE C_DAY_NEXT_YEAR; RETURN 'Faltan '||V_DAYS||' Días para tu cumpleaños'; END IF; ELSE OPEN C_DAY_NEXT_YEAR(V_UR_BIRTH); FETCH C_DAY_NEXT_YEAR INTO V_DAYS; CLOSE C_DAY_NEXT_YEAR; RETURN 'Faltan '||V_DAYS||' Días para tu cumpleaños'; END IF; EXCEPTION WHEN OTHERS THEN RETURN 'Formato de fecha Valido: Día/Mes/Año, Eje: 14/02/1993'; END; / SHOW ERROR-- Muestra errores de sintaxis al momento de Compilar.
/* Por supuesto esta función podría optimizarse mucho más, pero para los fines, asumiremos que es cumple el requerimiento deseado.*/
Usando dicha Función:
SELECT
HIRE_DATE AS "FECHA DE NACIMIENTO",
SYSDATE AS HOY,
DAYS_TO_BIRTHDAY(HIRE_DATE) AS "Mi Cumple"
FROM HR.EMPLOYEES;
/* En el ejemplo anterior se muestra el HIRE_DATE(asumimos que es la fecha de nacimiento del empleado), la fecha actual y los días que faltan para su cumpleaños, usando Nuestra función.
*/
SELECT
DAYS_TO_BIRTHDAY(SYSDATE) AS "GOOD_1",
DAYS_TO_BIRTHDAY('12-09-2000') AS "GOOD_2",
DAYS_TO_BIRTHDAY(5) AS "BAD_1",
DAYS_TO_BIRTHDAY('SAF') AS "BAD_2"
FROM DUAL;