2012-01-25 18 views
15

A SAS le gusta continuar el proceso bien después de advertencias y errores, por lo que a menudo necesito desplazarme hacia atrás en las páginas del registro para encontrar un problema. ¿Hay una mejor manera? Me gustaría que se detenga tan pronto como aparezca el primer error o advertencia para que pueda solucionarlo y vuelva a intentarlo.¿Hay alguna manera de hacer que SAS se detenga con la primera advertencia o error?

+0

veo que SO responde preguntas acerca de la programación SAS: la migración de allí. – whuber

Respuesta

13

La opción ERRORES = 1 se sugirió anteriormente, pero eso solo detiene la escritura de los mensajes ERROR en el registro. Sugeriría otra opción del sistema, ERRORABEND, que evitará que el programa siga procesando la mayoría de los errores. No conozco una opción para finalizar el procesamiento debido a las advertencias, pero creo que podría agregar una macro como la siguiente para detener el procesamiento.

%macro check_for_errors; 
    %if &syserr > 0 %then %do; 
     endsas; 
    %end; 
%mend check_for_errors; 

data test1; 
    <data step code> 
run; 
%check_for_errors; 

Puede repetir la llamada a la macro después de cada etapa de su programa, y ​​debe terminar en el punto de que el código de error es cualquier cosa menos 0.

+1

Debería haber leído más sobre la opción ERRORES = ... eliminó mi respuesta y actualizó su respuesta –

+1

¿Hay algo así como la opción ERRORABEND que no causa la desconexión del servidor SAS? Utilizo EG conectado a un servidor UNIX externo y si bien sería genial detener el procesamiento en el primer error, ERRORABEND cierra la conexión al servidor, lo que demora un tiempo en restablecerse en la siguiente ejecución. – orh

+1

También puede verificar si '& syserrortext' no está vacío. Encuentro que esta variable se configura de manera más confiable que '& syserr'. –

2

frecuencia hago algo similar a RWill, pero envolver todo mi programa en una macro. Después de cada paso DATA, PROC SQL, PROC SORT, etc. Compruebo un código de error (& SYSERR o & SQLRC). Si no es cero, salto hasta el final.

Más detalles y código aquí: https://heuristically.wordpress.com/2012/02/09/return-codes-errors-sas/

no puedo usar endsas a causa de cómo el sistema de lotes de nuestra organización lleva a cabo programas independientes en una sola sesión de SAS RWill.

+0

¡Esto es genial! Solo lea la entrada del blog y lo estoy probando. Durante años, me ha dejado estupefacto que SAS no funcione de esta manera automáticamente. Pregunta rápida: ¿TENGO que usar la variable SQLRC al verificar errores PROC SQL, o solo si me preocupa recuperar el código de error SQL? Parece que SYSERR también funciona con PROC SQL pero quería verificarlo dos veces. ¡Gracias de nuevo! –

+1

@sparc_spread: Si no le importa manejar el error en PROC SQL, entonces no verifique el código de error. Un caso donde puedo pensar que esto puede ser útil es usar 'drop table foo;' y no importa si la tabla existe. – Andrew

+0

Impresionante, gracias de nuevo. –

3

Una opción es reemplazar run con run &g_cancel, y proc sql; con proc sql &g_noexec;. Inicialmente, &g_cancel y &g_noexec están desactivados, por lo que todo se ejecuta.

en golpear un error (ya sea %sys_rc, %sql_rc o el uso de referirse a la lógica de negocio) establece &g_cancel para cancelar y &g_noexec a noexec.

Esto debería evitar que se ejecuten los siguientes pasos: obviamente las variables macro se pueden omitir para los pasos que tienen que ejecutarse independientemente (por ejemplo, un tidy up) o verificar antes de realizar pasos puramente en macro.

Nota para los usuarios de Enterprise Guide: La única advertencia es que si está ejecutando múltiples elementos de código en la misma sesión tendrá que restablecer los términos de error al inicio de cada elemento de código, no sea que los errores no relacionados detengan el funcionamiento.

+0

Creo que te refieres a 'reemplazar' ejecutar 'con' ejecutar y cancelar '' en la primera oración –

3

He estado usando la macro %runquit recientemente. Funciona bien para trabajos por lotes y sesiones interactivas (no cierra la sesión, simplemente deja de ejecutar el código).

Fuente: http://www.cpc.unc.edu/research/tools/data_analysis/sas_to_stata/sas-macros/runquit.html

Para utilizarlo es básicamente escribir %runquit; al final de cualquier paso de datos o PROC en lugar de escribir su habitual run o quit comunicado.

Código:

%macro runquit; 
    ; run; quit; 
    %if &syserr. ne 0 %then %do; 
    %abort cancel; 
    %end; 
%mend runquit; 

uso Datastep:

data something; 
* do some stuff; 
%runquit; 

uso PROC:

proc sql; 
    * do some stuff; 
%runquit; 

No es tan bonito cuando la lectura a través del código, pero sí hacer que la depuración de un montón más fácil.

2

Como complemento a la respuesta de Rwill:

Si está utilizando un proceso almacenado (STP), que es también muy agradable para no mostrar el registro a los usuarios cuando se produce un error y para eliminar el "registro Mostrar SAS" botón .

que se pueden lograr con esta fuente

%macro checkcc; 
    options obs=max no$syntaxcheck; 
    %if (&syscc gt 4) %then 
     %do; 
      data _null_; 
       file _webout; 
       put "<h3>Sorry, your request was not processed successfully.<h3>"; 
       rc = stpsrvset('program error', 0); 
      run; 
     %end; 
    %let syscc=0; 
%mend checkcc; 
%checkcc; 

: http://support.sas.com/kb/16/225.html

Y aquí es una versión mejorada que hice para mostrar aún el error en el formato JSON.

%macro checkErrors; 
    options obs=max no$syntaxcheck; 
    %let old = %sysfunc(stpsrv_header(Content-type, application/json%str(;) charset=utf-8)); 
    %put &=syscc; %put &=syserr; %put &=sysrc; %put &=syswarningtext; %put &=syserrortext; 
    %if (&syscc gt 4) %then %do; 
     data _null_; 
      file _webout; 
      put '{'; 
      put ' "success":"false"'; 
      put ' ,"message":"' "&syserrortext" '"'; 
      put ' ,"syscc":"' "&syscc" '"'; 
      put '}'; 
      rc = stpsrvset('program error', 0); 
      run; 
     %end; 
    %let syscc=0; 
%mend checkErrors; 
%checkErrors; 

y HTML versión:

%macro checkErrors_HTML; 
    options obs=max no$syntaxcheck; 
    %if (&syscc gt 4) %then %do; 
     data _null_; 
      file _webout; 
      put '<!doctype html> '; 
      put '<html> '; 
      put ' <head> '; 
      put '  <title>Error</title> '; 
      put ' </head> '; 
      put ' <body> '; 
      put '  <h1>An Error Occured</h1>'; 
      put '  <p>' "&syserrortext" '</>'; 
      put ' </body>'; 
      put '</html>'; 
      rc = stpsrvset('program error', 0); 
      run; 
     %end; 
    %let syscc=0; 
%mend checkErrors_HTML; 
%checkErrors_HTML; 
+0

¡Muy bien! Es de suponer que también querría un '% abort' o' endsas; 'allí, para que el resto del programa no se ejecute innecesariamente? –

+0

@AllanBowe ¿Esto no requeriría '% checkErrors' muy a menudo en su programa? Solo coloco '% checkErrors' al final del STP, así que no estoy seguro de que sea útil abortar más. ¿Qué piensas? –

+0

correcto, si está al final del programa, entonces no es necesario abortar. Solo estoy pensando en términos de algunos de mis casos de uso (STP de larga ejecución) donde sería útil poder abortar en medio de un programa sin enviar errores al cliente. –

Cuestiones relacionadas