El punto que vamos a tratar aquí es cómo hacer que un programa que tenemos planificado no arranque y se ejecute entero en el momento en que el planificador lance en el proceso, sino que espere a alguna otra dependencia que tenga que, por la razón que sea, no está disponible en el planificador, por ejemplo, si estamos utilizando cron o algún planificador de tareas básico que no pueda gestionar dependencias, puede ser una buena idea comprobar antes que todas las tablas que necesitamos están actualizadas.
Para ello vamos a necesitar una macro (llamada ejecucion en el ejemplo de código), que contiene el bucle y el código a ejecutar. Lo primero que hacemos es evaluar la condición de ejecución (antes del bucle while), si la condición no es cierta, se ejecutará el contenido del bucle y si es correcta ejecutará el código.
En un paso data dentro del bucle calculamos la hora actual y la hora límite que queremos dar al proceso (en este caso, la hora límite son las 22:00PM). Con esta hora límite, evitamos que el proceso se quede embuclado hasta el infinito en caso de que la condición que hemos establecido para num_tablas_actualizadas no se de nunca. Las funciones de fecha que se utilizan las hemos explicado en SAS: Operaciones con fechas y los formatos de fecha en Formatos de fecha en SAS.
La función sleep() debe ir dentro de un paso data y obliga a esperar al proceso por un periodo de tiempo. Puede tener uno o dos parámetros. Si solo le damos uno ese serán el número de unidades a esperar con la particularidad de que las unidades en un sistema Windows serán segundos y en otro basado en Linux, serán milisegundos. La forma de hacer que el código sea portable entre sistemas distintos es darle dos parámetros de forma que el primero siguen siendo el número de unidades y el segundo indicará cual es esa unidad. Por ejemplo, 1 significará segundos y 0.001 milisegundos.
Como último paso del bucle while se vuelve a evaluar la condición de ejecución (en el proc sql) y se comienza una nueva iteración en la que se comprueba esa condición y también se comprueba que no se haya llegado a la hora límite. Si se cumplen las condiciones el flujo se saltará el bucle y comenzará con la ejecución del resto del código.
%macro ejecucion();
proc sql noprint;
select count(*) into :num_tablas_actualizadas
from XXXXXX where YYYYYY
;quit;
%put "WARNING: Hay &num_tablas_actualizadas tablas actualizadas a la hora de inicio del proceso.";
%do %while (&num_tablas_actualizadas ne 5);
data _null_;
call symput('a',put(datetime(),datetime20.));
call symput('b',put(dhms(date(),22,00,0),datetime20.));
x=sleep(15,60);
run;
%put "WARNING: Hay &num_tablas_actualizadas tablas actualizadas a las &a";
proc sql noprint;
select count(*) into :num_tablas_actualizadas
from XXXXXX where YYYYYY
;quit;
data _null_;
if &a > &b then do;
%put "WARNING: Ejecución terminada al superarse la hora límite.";
stop;
end;
run;
%end;
/* inicio del proceso */;
%mend;
%ejecucion;