Error handling sas宏中的错误处理

Error handling sas宏中的错误处理,error-handling,sas,sas-macro,proc-sql,Error Handling,Sas,Sas Macro,Proc Sql,我正在编写一个简单的宏来计算表中所有列中的不同值。 我需要包括一个错误处理程序,它显示错误信息,如果在第一个表中找到某个列,但在第二个表中找不到,则需要进一步执行宏 例如, 比如说,我编写了一个宏来计算任何数据集中col1、col2、col3的不同值,以及 表1有列(col1、col2、col3) 但是 表2有列(col2,col3)-因此表2中不存在col1的错误。我需要一种方法来处理这个错误。我喜欢SAS,但我讨厌它中的错误处理(因为它几乎不存在,而且几乎总是需要使用宏代码来完成……糟糕)

我正在编写一个简单的宏来计算表中所有列中的不同值。 我需要包括一个错误处理程序,它显示错误信息,如果在第一个表中找到某个列,但在第二个表中找不到,则需要进一步执行宏

例如, 比如说,我编写了一个宏来计算任何数据集中col1、col2、col3的不同值,以及

表1有列(col1、col2、col3) 但是
表2有列(col2,col3)-因此表2中不存在col1的错误。我需要一种方法来处理这个错误。

我喜欢SAS,但我讨厌它中的错误处理(因为它几乎不存在,而且几乎总是需要使用宏代码来完成……糟糕)

您最好在执行代码之前检查任何条件,如果未满足任何要求,则您的一些选项包括:

  • 在运行步骤之前,使用描述性消息中止。我发现
    %abortcancel
    语句是在批处理和交互式会话中停止代码的最好方法
  • 使用
    %if%then
    语句跳过将失败的步骤
  • 让代码优雅地修复问题并继续(如果可能的话)。这可以通过有条件地运行通常不属于常规作业流的其他代码来实现
  • 运行它,然后重置错误条件(即将
    &syserr
    设置为零)?我从来没有真正玩过这个选项,所以我不能100%确定它是如何工作的,即使它是可行的
在您的情况下,我想象您的代码将如下所示:

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;
有几件事。。。我使用了一个名为
%nobs()
的宏来帮助我确定diff_columns数据集中是否存在任何OBERVATIONS。%nobs有许多不同的版本

如果您决定在不运行任何代码的情况下让SAS结束,下面将显示一个很好的宏。如果以批处理模式运行,它将退出SAS,但如果以交互方式运行,它将取消其余提交的代码而不离开SAS:

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

如果您想阻止SAS一旦遇到任何错误就将日志堆叠起来,请考虑使用<代码> %RunCuxMe宏。如下所示,以及使用说明:


SAS中的错误处理是一项相当混乱的工作,虽然这给了您一些统计的地方,但我确信这个列表绝不全面。我建议您尝试上面列出的几种不同方法,然后选择最适合您的方法…

建议您在问题中加入宏。并详细描述错误处理的含义。在完全没有工作的情况下,将在日志中报告错误,并且根据系统选项,SAS将继续处理或异常终止。那么你想要什么样的错误处理呢?是的,我基本上也是这样做的
&syserr
&syserrotext
是您最好的朋友。它慢慢地变成了一个混乱的跳跃,根据发现的内容跳转到程序的不同部分,使得一个简单的表更新程序相当大;然而,由于应用程序的重要性,这是必要的。不过,它变得相当健壮了!另一种方法是对原始列进行完整性约束。回想起来,如果我刚刚在事务数据集上创建了一组完整性规则,我本可以节省大量的代码。谢谢Robert!这个答案真的很有帮助。请注意%stop_sas宏在sas Studio或sas EG中无法正常工作。
%macro runquit;
  ; run; quit;
  %if &syserr %then %abort cancel;
%mend;