Archivo
Tareas programadas en entornos Oracle
En varias ocasiones he encontrado clientes con dudas sobre cómo se ejecutan las tareas programadas en sus sistemas Oracle (BBDD y servidores). No tienen claro quién es el responsable de su programación y ejecución, y esto puede ser un problema en caso de tener que modificarlas o desactivarlas.
A grandes trazos, podemos ejecutar tareas de 4 formas:
- Sistema operativo
- Tareas de la consola de administración
- Jobs de BBDD
- Scheduler de BBDD
Sistema operativo
Podemos programar tareas desde sistema operativo mediante el “crontab” en entornos Unix/Linux o el “Programador de tareas” en Windows.
Es bueno saber que en el caso concreto de los entornos Linux las tareas programadas en el crontab se almacenan de manera particular para cada usuario (cada uno puede tener las suyas) y, además, existen unos directorios de cron “horario”, “diario” y “mensual” en los que si dejamos algún script se ejecutará en esos intervalos de tiempo.
Tareas de la consola de administración
Podemos programar tareas desde la DBConsole o el Enterprise Manager/Grid Control, almacenándose en la BBDD de repositorio de estos productos. Pueden realizar tareas de todo tipo, sobre diferentes objetivos locales y remotos, hosts, BBDD, Servidores de Aplicaciones… (en el caso de objetivos remotos mediante agentes y solo en el caso del EM/GC).
Es bueno saber que estas tareas pueden generar confusión en el caso de la DBConsole, ya que en muchos casos se confunden con tareas de BBDD. Si por ejemplo programamos una “Tarea de Backup de BBDD” desde la DBConsole, se programará como una tarea de consola y solo podremos controlar su ejecución y logs desde la misma, además no se ejecutará si la consola está parada. En la siguiente imagen podemos ver el link de las tareas programadas en la DBConsole:
Jobs de BBDD
Estas eran las tareas típicas de BBDD hasta la versión 9.2. Consisten en un programador “simple” que permite ejecutar código PL/SQL o SQL de manera repetitiva a ciertos intervalos. Podemos programar estas tareas mediante el paquete de PL/SQL DBMS_JOB y controlar las tareas que tenemos programadas en la tabla DBA_JOBS (las que están en marcha en DBA_JOBS_RUNNING).
Es bueno saber que si el código programado no finaliza correctamente la tarea se intentará repetir a intervalos de tiempo que se irán doblando en cada iteración (en 1 minuto, en 2 minutos, en 4 minutos… hasta llegar al tiempo programado de la próxima ejecución “normal” prevista), al llegar a los 16 intentos la tarea se marcará como “broken” y no se repetirá. Esto es importante si tenemos una tarea que realiza ciertas modificaciones parciales antes de fallar, ya que estas modificaciones parciales se podrían repetir múltiples veces.
Otro detalle interesante es que podemos decidir cuántas tareas se pueden ejecutar simultáneamente (o parar completamente la ejecución de tareas) mediante el parámetro de inicialización “JOB_QUEUE_PROCESSES”, este parámetro es dinámico (lo podemos cambiar sobre la marcha sin parar el gestor). Por ejemplo si lo definimos a cero dejan de ejecutarse tareas mediante el sistema de JOBS.
Scheduler de BBDD
Finalmente tenemos el “SCHEDULER”, un sistema avanzado de programación de tareas aparecido en la versión 10g de la BBDD y que se ha ampliado y mejorado en versiones posteriores. Podemos crear una biblioteca de tareas, lanzar scripts de sistema operativo, crear cadenas de trabajos, ejecuciones condicionadas a eventos, ventanas de ejecución, vincular tareas al gestor de recursos, etc. En resumen, mucho más potente que el anterior sistema de jobs.
Se pueden programar las tareas mediante el paquete DBMS_SCHEDULER o desde el apartado de tareas de la BBDD en la DBConsole o en el EM/GC. Este es el sistema recomendado para programar tareas en las BBDD 10g y superiores.
En la siguiente imagen tenéis el resumen de componentes que forman el scheduler y sus relaciones:

Es bueno saber que si nos interesa arrancar la BBDD sin que se ejecute ningún job del scheduler, y estamos en versión 11.2, podemos definir a cero el parámetro job_queue_processes ya que en esta versión no solo desactiva los DMB_JOBS sino también los trabajos del scheduler. Para otras versiones tendremos que arrancar la BBDD en modo MIGRATE o UPGRADE y ejecutar el siguiente código:
exec dbms_scheduler.set_scheduler_attribute(‘SCHEDULER_DISABLED’,'TRUE’);
En la siguiente imagen tenéis la entrada de la DBConsole correspondiente a la programación de tareas en el Scheduler:
soapUI: Probar Web Services de forma rápida y efectiva
Cuando nos dedicamos a realizar proyectos de integración de sistemas mediante Web Services, lo más probable es que nos pasemos una buena parte de nuestro tiempo probando el funcionamiento de los mismos, ya bien para testear el buen funcionamiento de los servicios que implementamos, o bien para hacer pruebas de los servicios que debemos consumir.
Por tanto, es importante disponer, en nuestro arsenal de herramientas, de una herramienta que nos permita realizar estas pruebas de una forma rápida. Hoy os sugiero utilizar la que estoy utilizando yo actualmente en distintos proyectos: soapUI.
![]()
En primer lugar, las ventajas que veo a soapUI son las siguientes:
1) Existe una versión libre que cubre las necesidades de test básicas.
2) Nos permite generar con facilidad el esqueleto de una petición. Sólo debemos rellenarla con los valores que queremos probar y listo.
Prototipado con Justinmind Prototyper
Recientemente he empezado a trabajar con Justinmind Prototyper, una herramienta de prototipaje de aplicaciones, y debo decir que me parece una buena manera de reducir el coste de desarrollo, ya que permite identificar problemas de usabilidad o concepto con los usuarios antes de empezar la fase de construcción.
Se trata de una herramienta que permite adaptar los prototipos que creemos al look & feel de nuestra plataforma mediante plantillas y componentes propios. Pero más importante que eso es la facilidad con la que podemos añadir lógica de negocio, así como crear prototipos dinámicos gracias a los “data masters”, una especie de tablas de datos sobre los que podemos hacer las operaciones habituales que haríamos sobre una tabla de BD: añadir registros, borrar, modificar, filtrar, …
La posibilidad de crear pantallas a partir de “pantallazos” de una aplicación ya existente permite hacer propuestas a un Request For Change en muy poco tiempo: simplemente capturamos el formulario o página que deba ser modificada, pegamos la imagen en Prototyper, y sobre la imagen podemos añadir input texts, áreas sensibles al ratón que simulen algún comportamiento al ser clicadas, botones o enlaces que naveguen a otro módulo de la aplicación, etc.
Leer más…
Integración del calendario JS Calendar2 v1.8 en una aplicación web
Después del post que publiqué sobre cómo integrar el editor HTML CKEditor, he considerado interesante publicar este nuevo post tratando la integración de otra aplicación Javascript muy potente y usable: el calendario JSCalendar2.
Al igual que el CKEditor, estoy seguro que muchos de vosotros también conoceréis el JSCal y lo habréis integrado alguna vez en una aplicación web.
A continuación veréis los pasos para realizar una integración básica del calendario:
1. Lo primero es descargarse el zip de la web oficial: http://www.dynarch.com/projects/calendar/download/1.8/JSCal2-1.8.zip
2. Luego descomprimimos la carpeta JSCal2-1.8 directamente en la raíz de nuestro servidor web y le cambiamos el nombre a JSCal2.
3. Seguidamente creamos un HTML con las siguientes líneas de código:
Leer un archivo de texto mediante una consulta de BBDD
En Oracle existen las tablas externas que nos permiten vincular archivos de texto a tablas de base de datos. Este sistema es útil en numerosos casos, pero tiene el inconveniente que hay que declarar la estructura del archivo (columnas, separador, nulos…), tarea a menudo laboriosa. A veces sólo nos interesa poder consultar los datos de un archivo de forma ocasional. Vamos a detallar un método que nos permitirá leer mediante una consulta el contenido de un archivo sin necesidad de declarar tablas externas.
La solución propuesta consiste en la creación de una función que lee el archivo y devuelve el contenido de éste en un array. Para conseguir mejores resultados en el caso de archivos grandes, usaremos el método de las “pipelined table functions”, que nos permitirá ir devolviendo las líneas a medida que son leídas desde el archivo.
El primer paso será crear un tipo array de varchar2.
CREATE TYPE Ttb_archivo_texto AS TABLE OF VARCHAR2(4000);
A continuación creamos la función que lee el archivo. La función recibirá por parámetro el directorio de lectura y el nombre del archivo a leer. Devolverá el contenido del archivo en un array del tipo que acabamos de crear.
CREATE FUNCTION LEER_ARCHIVO (P_DIRECTORIO VARCHAR2, P_ARCHIVO VARCHAR2 ) RETURN Ttb_archivo_texto PIPELINED AS vArchivo utl_file.file_type; vLinea varchar2(4000); BEGIN vArchivo := utl_File.fopen (P_DIRECTORIO, P_ARCHIVO, 'R'); -- Leemos cada una de las líneas del archivo y la retornamos Loop Begin utl_file.get_line (vArchivo, vLinea); exception when NO_DATA_FOUND then exit; end; Pipe row (vLinea); end loop; utl_file.fclose (vArchivo); return; END; /
Ya podemos usar la función en una consulta. Para ello, vamos a llamarla en la cláusula FROM utilizando la función pl/sql “table”:
Select COLUMN_VALUE
from table (LEER_ARCHIVO ('OUT_SALDSV', 'test.txt'));
Nota: COLUMN_VALUE es el nombre que recibe por defecto la columna devuelta por la función de tabla.



