•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.
•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 mas, pero como el fin es de enseñanza, asumiremos que es cumple el requerimiento deseado.
*/
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.
*/
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 mas, pero como el fin es de enseñanza, 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;
/* En este ejemplo usamos la nuestra función pasandole la fecha actual, luego una cadena de caracteres con el formato valido de una fecha, luego le pasamos un numero entero y una cadena de caracteres no valida(las dos ultimas columnas mostrarían un mensaje de advertencia al usuario).
*/
*/