Para comenzar a migrar se va a explicar un método simple para migrar bloques anónimos y procedimientos. Si bien la forma mas prolija y estructurada es armar entidades PROGRAMS y SCHEDULER y luego asociarlas por medio de un JOB, vamos enfocarnos en una solución más cercana a la forma de programación antigua (usando dbms_job) para que el impacto de cambio sea menor y así fomentar el uso de dbms_scheduler.
Comparación de programación con DBMS_JOB y DBMS_SCHEDULER
Para comparar los dos paquetes para programación de tareas vamos a usar dos ejemplos de uso común. Se va a programar un bloque anónimo y luego se mostrará como programar la ejecución de código almacenado en la base de datos.
Usando DBMS_JOB
Ejecución de Bloque Anónimo
DECLARE l_job int; BEGIN DBMS_JOB.submit ( job => l_job, what => '', next_date => trunc(SYSDATE)+22/24, interval => 'trunc(SYSDATE+1) + 22/24'); COMMIT; END; Ejecución de procedimientos DECLARE l_job int; BEGIN DBMS_JOB.submit ( job => l_job, what => 'procedimiento>', next_date => trunc(SYSDATE)+22/24, interval => 'trunc(SYSDATE+1) + 22/24'); COMMIT; END;
Usando DBMS_SCHEDULER
Ejecución de Bloque Anónimo
Opción 1: Intervalo definido como se define con DBMS_JOB (modalidad vieja)
BEGIN DBMS_SCHEDULER.create_job ( job_name => 'job_1', job_type => 'PLSQL_BLOCK', job_action => '', start_date => trunc(SYSTIMESTAMP) + 22/24, repeat_interval => 'trunc(SYSTIMESTAMP+1) + 22/24', enabled => true); END;
Opción 2: Intervalo definido de forma mas simple y comprensible (modalidad nueva)
BEGIN DBMS_SCHEDULER.create_job ( job_name => 'job_1', job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN foo; END;', start_date => trunc(SYSTIMESTAMP) + 22/24, repeat_interval => 'FREQ=DAILY;BYHOUR=22;BYMINUTE=0;BYSECOND=0', enabled => true); END;
Como se ve en el ejemplo es muy sencillo definir los intervalos. Incluso se pueden definir días de la semana, días del mes, meses del año, etc. Para mayor detalle ver Calendaring Syntax en el manual “PL/SQL Packages and Types Reference 10g”
Ejecución de procedimientos
BEGIN DBMS_SCHEDULER.create_job ( job_name => 'job_1', job_type => 'STORED_PROCEDURE', job_action => '', start_date => trunc(SYSTIMESTAMP) + 22/24, repeat_interval => 'FREQ=DAILY;BYHOUR=22;BYMINUTE=0;BYSECOND=0', enabled => true); END;
Ventajas de usar DBMS_SCHEDULER
· Permite definir intervalos en forma mas expresiva y simple (Calendaring Sintax).
· Permite darle un nombre significativo al job. Con dbms_job se le asignaba un número interno del sistema.
· Se le puede definir prioridades de ejecución. Se pueden asociar ventanas de ejecución con planes de Resource Manager.
· Guarda registros historicos de detalle de ejecuciones, cantidad de corridas, errores, detalle de los errores, etc.
· Es mucho más sencillo matar un job programado desde dbms_scheduler que un job programado con dbms_job.
Consultas comunes para obtener información de programación DBMS_SCHEDULER
Para mostrar detalle de las corridas de los jobs:
select log_date, job_name, status, req_start_date, actual_start_date, run_duration from dba_scheduler_job_run_details
Para ver los jobs que están corriendo:
select job_name, session_id, running_instance, elapsed_time, cpu_used from dba_scheduler_running_jobs;
Para ver detalle de como están definidos los jobs:
select job_name, job_creator, job_type, job_action, start_date, repeat_interval, next_run_date enabled, run_count, failure_count from user_scheduler_jobs
Muy bueno.
ResponderEliminarMuchas gracias por la información, tengo una duda, cómo se si el paquete DBMS_SCHEDULER está instalado en mi versión de oracle, existe algún select para validar esto??
ResponderEliminarMuchas gracias, me ha servido de gran ayuda.
ResponderEliminarVen una pregunta, los DBMS_Jobs tenian la particularidad de que una vez se termina la ejecucion del proceso, estos son eliminados, esto permitia segmentar una reporte pesado, por ejemplo, en varias partes y manejarlos con varios user_jobs corriendo paralelamente y al finalizar el reporte todos los jobs eran eliminados y al ejecutarlo nuevamente se creaban nuevos jobs. Esto se puede hacer con DBMS_SCHEDULER?
ResponderEliminarPedro, claro que puedes hacer eso y mucho mas con dbms_scheduler. Para paralelizar como tu dices es ideal usar con dbms_schedureler los light weight jobs que se crear y eliminan mas eficientemente y requieren menos metadata. Te recomiendo la siguiente nota:
ResponderEliminarhttp://www.oracle-base.com/articles/11g/scheduler-enhancements-11gr1.php#lightweight_jobs