调用执行不在SAS中工作

时间:2015-09-22 18:42:58

标签: reference macros sas call execute

data numbers;
  input num;
  datalines;
  3
  1
  3
  ;
run;

%macro temp(num);
  proc sql noprint;
    select count(*) into :count from numbers;
  quit;
  %if (&num eq &count) %then 
    %put Match Found;
  %else 
    %put No Match Found;
  %symdel count;
%mend;

data _NULL_;
  set numbers;
  call execute('%temp('||num||')');
run;

为什么此代码显示错误,尽管一切正确。 我正在检查数据集编号中的值以查找之间的匹配 带有可变数字的整体计数(仅适用于练习) 在检查条件I之后,我使用proc SQL进行了计数 我正在删除count宏变量。后 执行为什么SAS提供错误消息。请解释一下 真的发生在这段代码中。

LOG-----when I execute the last data step--------->

    6188   data _NULL_;
    6189   set numbers;
    6190   call execute('%temp('||num||')');
    6191   run;

    NOTE: Numeric values have been converted to character values at the places given by:
                (Line):(Column).
                6190:24
    Match Found
    WARNING: Apparent symbolic reference COUNT not resolved.
    ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
                 operand is required. The condition was: &num eq &count
    ERROR: The macro TEMP will stop executing.
    WARNING: Apparent symbolic reference COUNT not resolved.
    ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
                 operand is required. The condition was: &num eq &count
    ERROR: The macro TEMP will stop executing.
    NOTE: The SAS System stopped processing this step because of errors.
    NOTE: There were 3 observations read from the data set WORK.NUMBERS.
    NOTE: DATA statement used (Total process time):
                real time           0.00 seconds
                cpu time            0.00 seconds


    NOTE: CALL EXECUTE generated line.
    1     + proc sql;
    1     +           select count(*) into :count from numbers;
    1     +                                                     quit;
    NOTE: PROCEDURE SQL used (Total process time):
                real time           0.09 seconds
                cpu time            0.00 seconds


    2     + proc sql;
    2     +           select count(*) into :count from numbers;
    2     +                                                     quit;
    NOTE: PROCEDURE SQL used (Total process time):
                real time           0.15 seconds
                cpu time            0.01 seconds


    3     + proc sql;
    3     +           select count(*) into :count from numbers;
    3     +                                                     quit;
    NOTE: PROCEDURE SQL used (Total process time):
                real time           0.15 seconds
                cpu time            0.01 seconds

2 个答案:

答案 0 :(得分:3)

当CALL EXECUTE()语句运行时,代码被压入堆栈。由于您没有使用任何宏引用,因此宏实际上正在运行,并且生成的代码被压入堆栈。因此%IF语句在SELECT语句运行之前运行。您可以使用%NRSTR()来延迟此操作,以便将宏调用推送到堆栈。

call execute(cats('%nrstr(%temp)(',num,')'));

或者只是避免CALL EXECUTE并使用PUT语句将代码写入您可以%INCLUDE的文件。

filename code temp;
data _null_;
  set numbers;
  file code ;
  put '%temp(' num ')' ;
run;
%include code / source2 ;

答案 1 :(得分:-1)

documentation page引用来执行调用:

  

注意:因为宏引用立即执行并且SAS   语句在步骤边界之后才执行,不能使用   CALL EXECUTE以调用包含宏引用的宏   由CALL SYMPUT在该宏中创建的变量。

我认为你在这里尝试做的事情基本上是同样的事情,只在你的宏中使用proc sql的{​​{1}}而不是select into

解决此限制的一种方法是使用call symput功能。您可以使用它来创建一个函数式宏,然后可以通过dosubl生成的%put语句运行:

call execute

或者,您可以将data numbers; input num; datalines; 3 1 3 ; run; %symdel COUNT; %macro temp(num); %sysfunc(dosubl(proc sql noprint; select count(*) into :count from numbers; quit;)) %if &num eq &count %then %put Match Found; %else %put No Match Found; %mend; data _NULL_; set numbers; count = symget('Count'); put "Before call execute " _n_= count=; call execute('%put rc=%temp('||num||');'); count = symget('Count'); put "After call execute " _n_= count=; run; 调用放入数据步骤而不是宏定义:

dosubl