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
答案 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