Sas обработка ошибок

Love SAS, but I hate error handling in it (as it’s near non-existent and almost always needs to be done using macro code… yuck).

Your best bet is to check for any conditions prior to executing the code, and if any requirements are not met then some of your options are:

  • Abort with a descriptive message prior to the step being run. I find that the %abort cancel statement is the nicest way to stop code in both batch and interactive sessions.
  • Skip the step that would fail using a %if %then statement.
  • Have the code gracefully fix the issue and continue (if that’s a possibility). This could be done by conditionally running additional code that’s not normally part of the regular job flow.
  • Have it run and then reset the error condition (ie. set &syserr to zero)? I’ve never really played around with this option so I’m not 100% sure how it works of even if it’s feasible.

In your case I imagine your code will look something like:

data have1;
  set sashelp.class;
run;

data have2;
  set sashelp.class(drop=age);
run;

/* GET A LIST OF COLUMNS IN EACH TABLE */
proc sql noprint;
  create table column_list as
  select memname, name
  from dictionary.columns
  where libname = 'WORK'
   and memname in ('HAVE1','HAVE2')
  order by name
  ;
quit;

/* CREATE A DATASET CONTAINING COLUMNS THAT ONLY EXISTS IN ONE OF THE TWO TABLES */
/* YOUR LOGIC MAY DIFFER */
data diff_columns;
  set column_list;
  by name;
  if first.name and last.name then do;
    output;
  end;
run;

%macro error_handling;
  %if %nobs(iDs=diff_columns) %then %do;  
    %put ERROR: TABLES CONTAINED DIFFERENT COLUMNS.;
    /* CHOOSE HOW YOU WANT TO HANDLE IT HERE */
  %end;
%mend;
%error_handling;

A few things… I’ve used a macro called %nobs() to help me determine if there are any obersvations in the diff_columns dataset. There are many different versions of %nobs, here is a selection.

If you decide you want to have SAS end without running any more code, a good macro for doing that is shown below. It will quit SAS if running in batch mode, but if you’re running interactively it will just cancel the remaining submitted code without leaving SAS:

%macro stop_sas;
  %if "&sysenv" eq "FORE" %then %do;
    %abort cancel;
  %end;
  %else %do;
    endsas;
  %end;
%mend;

If you want to stop SAS from cluttering up the log once it has encountered any errors, consider using the %runquit macro. It looks like this, and usage instructions can be found here:

%macro runquit;
  ; run; quit;
  %if &syserr %then %abort cancel;
%mend;

Error handling in SAS is a pretty messy business and while this gives you somewhere to stat I’m sure this list is by no means comprehensive. I’d suggest just try a few different approaches that I’ve listed above and then choose whatever worked best for you…

This tutorial explains how to make SAS stop macro execution on error. It is one of the most common task in building a macro. For example, you are building a macro for SAS users who are beginners. You need to make sure error handling in the macro. If user forgets to specify either a dataset name or variable name, macro should not execute further steps and it should abort immediately.

1. Stop Macro Processing on Error

In the following program, we are telling SAS to stop sas code if user does not specify parameters and notifying them what they have missed. The %abort cancel; statement tells SAS to abort execution immediately.

%macro explore(inputdata= ,var=);

options notes;

%if %length(&inputdata) = 0 %then %do;

%put ERROR: INPUTDATA= must be specified;

%put ERROR: The macro ended abnormally.;

%abort cancel;

%end;

%if %length(&var) = 0 %then %do;

%put ERROR: VAR= must be specified;

%put ERROR: The macro ended abnormally.;

%abort cancel;

%end;

proc sort data = &inputdata.;

by &var.;

run;

%mend;

%explore(inputdata =  , var = age );

Logic — If the length of string of a macro parameter is 0, it means the macro parameter is blank.

2. Go to End of Program If Error

In the following program, we are telling SAS to go to end of the code if error comes, The %goto statement is used to jump to end of the program.

%macro explore(inputdata= ,var=);
options notes;
%if %length(&inputdata) = 0 %then %do;
%put ERROR: INPUTDATA= must be specified;
%put ERROR: The macro ended abnormally.;
%goto exit;
%end;

%if %length(&var) = 0 %then %do;
%put ERROR: VAR= must be specified;
%put ERROR: The macro ended abnormally.;
%goto exit;
%end;

proc sort data = &inputdata.;
by &var.;
run;

%exit:
%mend;

%explore(inputdata = , var = age );

3. Check for Error after each step of SAS Code

Sometimes we make typo while entering dataset or variable name. It is important to handle these kinds of errors as well so we need to check for error(s) after each step of SAS Code (Data Step, PROCs).  %if &syserr. ne 0 %then %do; works for it.

%macro explore(inputdata= ,var=);
options notes;
%if %length(&inputdata) = 0 %then %do;
%put ERROR: INPUTDATA= must be specified;
%put ERROR: The macro ended abnormally.;
%abort cancel;
%end;
%if %length(&var) = 0 %then %do;
%put ERROR: VAR= must be specified;
%put ERROR: The macro ended abnormally.;
%abort cancel;
%end;
proc sort data = &inputdata.;
by &var.;
run;
%if &syserr. ne 0 %then %do;
%abort cancel;
%end;

%mend;
%explore(inputdata = sashelp.clss , var = age );

Tip

Instead of using %length to calculate the length of macro parameter, we can use COUNTW function. It is very useful to count the number of variables in the macro parameter.

%if %sysfunc(countw(&inputdata., %str( ))) = 0 %then %do;
%abort cancel;
%end;

About Author:

Deepanshu Bhalla

Deepanshu founded ListenData with a simple objective — Make analytics easy to understand and follow. He has over 10 years of experience in data science. During his tenure, he has worked with global clients in various domains like Banking, Insurance, Private Equity, Telecom and Human Resource.

Next →
← Prev

You should check for error return codes in any SAS programs that run unattended in batch jobs, so you can handle the exception properly. For example, if the data are invalid, you don’t want to generate reports or insert bad data into a database. Also it can save time to abort as soon as the error is detected.

Programming languages like Java and Python will often throw an exception which must be handled explicitly, and if it is not handled, then the program will stop. SAS, on the other hand, will blindly continue executing commands after an error.

The solution is to wrap the entire SAS program in a macro. After each SAS command (DATA step, PROC SQL, PROC SORT, etc.) check for an error code. For PROC SQL, I check &SQLRC; for everything else, I check &SYSERR. If the return code is non-zero, I jump to the end. In some cases, I print an error message to the SAS log.

In the following example are three procedures, and each contains an error. If you run at is, the second two will not run. Fix the first error, and run again: this time the last procedure will not run.

%macro sortclass;

proc sql;
	create table class as
	select
		*
	from
		sashelp.classs /* typo */
	;
quit;

%if &SQLRC gt 0 %then %do;
 %put ERROR: PROC SQL failed, so I will not continue.;
 %goto exit;
%end;

data class;
	set class;

	format bmi 10.1.; /* fix: remove the period at the end */
	bmi = weight/height;
run;

%if &SYSERR gt 0 %then %goto exit;

proc sort data=class;
	by doesnotexist; /* fix: change 'doesnotexist' to 'bmi' */
run;

%if &SYSERR gt 0 %then %goto exit;

%exit:
%mend;

%sortclass;

If you execute multiple commands (SELECT, INSERT, DROP, etc.) in one PROC SQL, then check &SQLRC after each command.

Instead of going to one exit point, you may have two jump labels: exit and error. In the error label, you can send an email asking a human to check the SAS logs. Example:

%macro sortclass;

proc sql;
	create table class as
	select
		*
	from
		sashelp.classs /* fix: remove the extra 's' */
	;
quit;

%if &SQLRC gt 0 %then %goto error;

%goto exit; /* there is no error */

%error:
filename mymail email "andrew@example.com" subject="error in SAS program";
   data _null_;
      file mymail;
      put 'check the logs';
   run; 

%exit:
%mend;

%sortclass;

One unpleasant side effect of wrapping the program in a macro is SAS 9.2 (at least on Windows) loses syntax highlighting for the non-macro bits such as PROC SQL and DATA steps.

Checking return codes is one technique that is part of a larger strategy of error checking. For example, you can add automated checks that that a data set has any or enough observations, that duplicates keys do not exist, that the values are not missing, that numerics are within normal ranges, etc. If you have a macro that attaches variables to an arbitrary input data set, then the input data set should not already have the same variable that will be attached: this can lead to unexpected results. And depending on your situation, there are many other things that can be checked.

Update (March 2016): See the new post In case of error in SAS program, send email and stop, which focuses on a lighter-weight approach that does not lose syntax hightlighting.

Related posts

#error-handling #sas

#обработка ошибок #sas

Вопрос:

У меня ожидаемая ошибка с amp;syserr. of 1020 . При возникновении ошибки программа завершает работу со следующим сообщением:

 FATAL: Unrecoverable I/O error detected in the execution of the DATA step program.
       Aborted during the EXECUTION phase.
  

Я знаю, в чем проблема, и для нее нет решения. Однако, поскольку я знаю, что вызывает проблему, я хочу предупредить пользователя о том, как это исправить, до завершения работы программы.

То есть между возникновением ошибки и прерыванием программы я хочу выполнить некоторый код.

Я прочесал Интернет и не смог найти ничего, что говорило бы, что это невозможно сделать. На самом деле, многие ответы на SO подразумевали, что это можно сделать. Но я понятия не имею, как.

Комментарии:

1. Как вы запускаете программу? Интерактивный? Пакет?

2. Я думаю, технически интерактивный. Я нахожусь в оконной среде SAS, используя улучшенный редактор. Я выбираю инструкции, которые хочу выполнить, а затем нажимаю «Отправить». Код, который выдает ошибку, существует в макросе.

3. Когда вы говорите «прервано», вы просто имеете в виду, что этап передачи данных завершается? Или SAS завершается? Или макрос завершается неправильно?

4. Код прекращает выполнение, и управление возвращается расширенному редактору. В журнал записывается сообщение об ОШИБКЕ. В идеале я хотел бы выполнить код между возникновением ошибки и записью сообщения об ошибке. Я знаю, что в SAS нет конструкции try / catch, поэтому я надеюсь, что может существовать механизм типа «on error goto». antonis.de/qbebooks/gwbasman/onerror.html

5. После того, как это произойдет, если вы отправите еще один небольшой шаг С ДАННЫМИ, это сработает? Или вся ваша интерактивная сессия в значительной степени нарушена, и вам нужно закрыть SAS и перезапустить?

Ответ №1:

Поскольку вы знаете, что установлен параметр amp;syserr, одним из вариантов было бы написать свой собственный макрос %onError, что-то вроде:

 %macro OnError(debug=0);
  %if amp;syserr ne 0 %then %do;
    %*blah blah blah;
  %end;
%mend OnError;
  

Итак, ваш код выглядит следующим образом:

 data want;
  set have;
  oops;
run;
%OnError()
  

Обратите внимание, что amp;syserr сбрасывается после каждой границы шага, поэтому вам нужно протестировать его сразу после подозрительного шага. Существуют другие переменные макроса с кодами возврата, которые сохраняются.

Если ошибка была достаточно серьезной, чтобы SAS перешла в режим проверки синтаксиса (установите obs = 0 и noreplace), вам пришлось бы сделать больше для восстановления. Но я думаю, что по умолчанию в interactive SAS это отключено.

Комментарии:

1. Я думаю, что если бы это была обычная ошибка, это было бы совершенно правильно. Однако я думаю, что ошибка, на которую он ссылается, не следует за этими строками — это скорее ошибка в SAS code supervisor или что-то еще, где она перегружается. Хотя и не уверен.

2. Это позволяет мне выполнять код, хотя я не могу найти способ предотвратить прерывание. Например, я могу написать сообщение в журнал, в котором более подробно описывается, почему программа прерывается. Кажется, я не в состоянии предотвратить прерывание.

3. Согласен, это не позволит избежать прерывания или сообщения об ошибке. Это может быть использовано для «восстановления» в смысле повторной попытки выполнения шага (если это была проблема с сетью или аналогичная) или запуска альтернативного шага, или отправки кому-либо электронного письма и т.д. Но это не похоже на настоящую попытку … поймать. Я думаю, что вы застряли, пытаясь либо избежать ошибки, либо восстановиться после возникновения ошибки.

Ответ №2:

Хотя это неуклюже, желаемого результата можно достичь с помощью операторов %LABEL и %GOTO.

Необходимо учитывать, что

«метка, которая является целью инструкции %GOTO, должна существовать в текущем макросе; вы не можете перейти к метке в другом макросе с помощью инструкции %GOTO».

Поскольку ошибка возникает в коде, уже содержащемся в макросе, отдельный макрос не может использоваться для обработки события ошибки. (SAS рекомендует не создавать макросы внутри других макросов).

Комментарии:

1. Хороший улов. Я не смог придумать пример, который эмулирует мою проблему, поэтому я удалил пример, на который вы ссылаетесь. Мы надеемся, что ваш ответ вместе с %goto /% label должен предоставить достаточную информацию для процветания.

Several statements, options, functions, and programming alternatives are well suited to controlling how and when all or a portion of a program can be stopped conditionally.

Sometimes we want to control the flow of the individual data steps of the program. This may include the termination of a step or even the SAS job itself. Several exit strategies depend on the objective.

1. STOP Statement

The STOP statement stops the execution of the current DATA step immediately and resumes processing the statements after the end of the current DATA step.

SAS writes a data set for the current DATA step. However, the observation being processed when STOP executes is not added. The STOP statement can be used alone or in an IF-THEN statement or SELECT group.

STOP does not set the system error conditions, and the job continues executing with the next step.

2. ABORT Statement

ABORT statement is used to stop executing the current DATA step, SAS job, or even a SAS session.

Syntax:

ABORT <ABEND | CANCEL <FILE> | RETURN> <n> <NOLIST>;
ERROR: Execution terminated by an ABORT statement at line 73 column 18.

The ABORT statement is usually used when error conditions are identified. Like the STOP statement, ABORT also stops the execution of the current data step. The behaviour of this statement depends to some extent on the operating system and whether the job is being run under batch or interactive modes.

ABORT writes an error message to the log and sets the system error conditions. In batch mode, ABORT sets OBS=0 and continues limited processing.

Arguments

In interactive mode, ABORT acts like STOP. The ABORT statement can be used with two options, ABEND and RETURN.

ABEND – With the ABEND option, ABORT writes an error message to the log and returns control to the host system as an abnormal termination.

CANCEL <FILE> – It causes the execution of the submitted statements to be cancelled. Actions depend on the method of operation.

FILE – when coded as an option to the CANCEL argument in an autoexec file or in a %INCLUDE file, causes only the contents of the autoexec file or %INCLUDE file to be cleared by the ABORT statement. Other submitted source statements are executed after the autoexec file or %INCLUDE file.

RETURN The RETURN option is the same as ABEND but exits from SAS as a normal termination. For operating systems that support it, a return code can also be specified with the ABEND and RETURN options.

n is an integer value that enables you to specify a condition code.

  • when used with the CANCEL argument, the value is placed in the SYSINFO automatic macro variable.
  • when not used with the CANCEL argument, the error code that is returned by SAS is ERROR. The value of ERROR depends on the operating system. The condition code n is returned to the operating system as the final SAS System exit code.

NOLIST – It suppresses the output of all variables to the SAS log.

Example:

%macro sort(inputdsn=, ByVar=, outDSN=);
	%if %length(&inputdsn)=0 %then
		%do;
			%put ERROR: Input Dataset must be specified;
			%abort cancel;
		%end;
	%if %length(&Byvar)=0 %then
		%do;
			%put ERROR: By Variable must be specified;
			%abort cancel;
		%end;
	proc sort data=&inputdsn. out=&outdsn.;
		by &byvar.;
	run;

%if &syserr. ne 0 %then
%do;
%abort cancel;
%end;
%mend;
%sort(inputdsn=sashelp.class , byvar=, outdsn=class);
ERROR: By Variable must be specified ERROR: Execution canceled by an %ABORT CANCEL statement.

3. ENDSAS

ENDSAS Terminates a SAS job or session after the current DATA, or PROC step executes.

Note: ENDSAS statements are always executed at the point that they are encountered in a DATA step. Use the ABORT RETURN statement to stop processing when an error condition occurs (for example, in the clause of an IF-THEN statement or a SELECT statement).

The entire job is terminated in the following data step if the variable X is ever less than or equal to zero.

data new;
	set old;
	lnx=log(x);
	if _error_ then
		endsas;
run;

4. RUN CANCEL

The CANCEL option on the RUN statement prevents the current step from being executed. This is a quick way to prevent code from executing instead of using comments.

You can skip a code with the RUN CANCEL statement. Including the option CANCEL on the run;

statement terminates the current step without executing it.

proc print data=sashelp.class;
	var age;
run cancel;

SAS also prints a message that indicates that the step was not executed.

WARNING: The procedure was not executed at the user's request.

The Cancel option has no effect where the data step has the datalines statement or the run statement has no effect, such as with PROC SQL. Also, it has no effect when you use the KILL option with PROC DATASETS.

Read more on Skipping codes.

5. ERRORABEND

Like the ABORT and ENDSAS statements, the system option ERRORABEND specifies how SAS responds to errors. terminates the SAS session or job. Since this is an option, no IF-THEN-ELSE processing is required.

As soon as the first error is encountered, the job terminates. This option does not terminate for data errors but is primarily directed to syntax errors and other errors that would otherwise cause the system to go into syntax check mode.

When ERRORABEND is used in an interactive session, termination may also eliminate the LOG. Thus any clues as to the reason for the termination will also be eliminated.

Syntax

ERRORABEND | NOERRORABEND

ERRORABEND – It specifies that SAS stops abnormally for most errors (including syntax errors) that would normally cause it to issue an error message, set OBS=0, and go into a syntax-check mode (in batch mode only). ERRORABEND does not affect how SAS handles notes, such as invalid data messages.

NOERRORABEND – It specifies that SAS handles errors normally, issues an error message, sets OBS=0, and goes into a syntax-check mode (in batch mode only).

Subhro provides valuable and informative content on SAS, offering a comprehensive understanding of SAS concepts. We have been creating SAS tutorials since 2019, and 9to5sas has become one of the leading free SAS resources available on the internet.

Понравилась статья? Поделить с друзьями:
  • Sarah and i am sisters найти ошибку
  • Sapphire rx 470 4gb nitro ошибка 43
  • Sap ошибка при считывании свойств объекта
  • Sap ошибка доступа к приложению ms excel
  • Sap ошибка v1382