我遇到了使用proc sql select into :
逻辑创建宏变量的问题。代码似乎非常简单,但我应该注意,导致问题的宏是从其他几个宏调用的。
以下是导致问题的代码段。
%do year_num=1 %to 5;
%if &year_num=1 %then %let min_date = %eval(&max2.-17);
%else %let min_date = %eval(&min_date.-12);
data tmp;
set bf(firstobs=&min_date obs=%eval(11+&min_date));
run;
data tmp2;
set bf(firstobs=%eval(5+&min_date) obs=%eval(7+&min_date));
run;
proc sql noprint;
select sum(EP), sum(ExpectedLoss)
into :totep, :totexpt
from tmp;
select sum(EP), sum(ExpectedLoss)
into :partep, :partexpt
from tmp2;
quit;
%put _LOCAL_;
*Other code...;
%end;
出于某种原因,变量totep
,totexpt
,partep
和pqrtexpt
未创建,我无法在日志中找到任何有用的信息这可能会对情况有所了解。
以下是日志的一部分,包括_LOCAL_
的输出。
SYMBOLGEN: Macro variable YEAR_NUM resolves to 1
SYMBOLGEN: Macro variable MAX2 resolves to 96
MPRINT(BFMETHOD): data tmp;
SYMBOLGEN: Macro variable MIN_DATE resolves to 79
SYMBOLGEN: Macro variable MIN_DATE resolves to 79
MPRINT(BFMETHOD): set bf(firstobs=79 obs=90);
MPRINT(BFMETHOD): run;
MPRINT(BFMETHOD): data tmp2;
SYMBOLGEN: Macro variable MIN_DATE resolves to 79
SYMBOLGEN: Macro variable MIN_DATE resolves to 79
MPRINT(BFMETHOD): set bf(firstobs=84 obs=86);
MPRINT(BFMETHOD): run;
MPRINT(BFMETHOD): proc sql noprint;
MPRINT(BFMETHOD): select sum(EP), sum(ExpectedLoss) into :totep, :totexpt from tmp;
MPRINT(BFMETHOD): select sum(EP), sum(ExpectedLoss) into :partep, :partexpt from tmp2;
MPRINT(BFMETHOD): quit;
BFMETHOD I 12
BFMETHOD DSET all
BFMETHOD SEAS_MIN 0.6
BFMETHOD YEAR_NUM 1
BFMETHOD SEAS_MAX 1.66666666666666
BFMETHOD MIN_DATE 79
data tmp; set bf(firstobs=79 obs=90); run;
NOTE: There were 12 observations read from the data set WORK.BF.
NOTE: The data set WORK.TMP has 12 observations and 35 variables.
NOTE: Compressing data set WORK.TMP increased size by 100.00 percent.
Compressed is 2 pages; un-compressed would require 1 pages.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
109 + data tmp2; set bf(firstobs=84 obs=86); run;
NOTE: There were 3 observations read from the data set WORK.BF.
NOTE: The data set WORK.TMP2 has 3 observations and 35 variables.
NOTE: Compressing data set WORK.TMP2 increased size by 100.00 percent.
Compressed is 2 pages; un-compressed would require 1 pages.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
109 + proc sql noprint;
109 + select sum(EP), sum(ExpectedLoss) into :totep, :totexpt from tmp;
109 +
select sum(EP), sum(ExpectedLoss) into :partep, :partexpt from tmp2;
109 +
quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
如果我从noprint
语句中删除proc sql
,则会输出正确的值,因此我不确定发生了什么。任何帮助将不胜感激。
答案 0 :(得分:2)
您的问题几乎肯定与执行时间有关。特别是在使用call execute
时,您很容易遇到SAS处理器解决宏变量的时间问题,而不是给定有用的值。
这是一个简化的例子。我专门创建了一个数据集,以便您可以看到何时发生(这不是必要的步骤,也不会影响示例,它只是创建一个有用的日志条目)。
请注意,当宏运行时,一切都按照您的预期运行;但是当它与call execute
一起运行时,%put
执行之前宏实际执行。
第三个示例使用%nrstr
强制SAS在实际运行宏之前不尝试解析宏 - 这会导致正确提交宏。
实际上,第一个call execute
版本有SAS处理宏文本,然后将其提交给sas.exe - 这是你真的不想要的。添加%nrstr
修复了。
%macro do_something();
%local mlist;
data class_m;
set sashelp.class;
where sex='M';
run;
proc sql;
select name into :mlist separated by ' '
from class_m;
quit;
%put &=mlist;
%mend do_something;
%put Macro run on its own;
%do_something;
%put Macro run via call execute;
options mprint symbolgen;
data _null_;
set sashelp.class;
if _n_=1 then call execute('%do_something()');
stop;
run;
%put Macro run with nrstr and call execute;
data _null_;
set sashelp.class;
if _n_=1 then call execute('%nrstr(%do_something())');
stop;
run;