我有一个代码尝试使用子查询中的宏变量更新宏块中的表。我遇到的挑战是有时一些宏变量为空,从而使代码失败。当宏变量产生空值时,如何将其设置为忽略?
%macro update_bucket;
%let macro_fudge = %nrstr(%mend);
proc sql;
%do i=1 %to &rows.;
%do j=1 %to &max_comb.;
%do k=1 %to &max_LGD_comb.;
%do l=1 %to &max_PD_comb.;
%let x = _&&k.LGD&i.;
%let y = _&&l.PD&i.;
%if &x. ^=LTV %then %do;
update sbbook_rb_A as a
set riskbucket = (select risk_bucket from PORTFOLIO_SPLIT_D as b
where a.businessgroup = b.portfolio
and a.product2 = b._&j.subport
and a.&&&x. >= b.min_lgd_driver_%left(&k.) /* at times "a.&&&x." returns a null value */
and a.&&&x. < b.max_lgd_driver_%left(&k.)
and a.&&&y. >= b.min_pd_driver_%left(&l.) /* at times "a.&&&y." returns a null value */
and a.&&&y. < b.max_pd_driver_%left(&l.)
and b.row_num = &i.
)
where riskbucket = '';
%end;
%end;
%end;
%end;
%end;
quit;
%mend;
%update_bucket;
谢谢
答案 0 :(得分:2)
在大多数情况下,最佳做法是使用参数,而不是全局宏变量。在这种情况下,您可以为它们提供一个默认值,然后您可以测试并跳过循环(例如,您可以给出默认值0)。
%macro mymacro(param1=0, param2=0);
...
%mend mymacro;
你应该从不依赖于你在该代码中所做的方式,无论如何;宏中使用的任何宏变量都应该是宏的参数,除了路径之类的非常明显的全局事物(即便如此,我更喜欢那些参数)。您可以将全局值作为参数传递给参数,但应明确传递。
答案 1 :(得分:1)
测试宏var是否为空的几种方法:
%If &&&x= %then
%If &&&x=%str() %then
%If %length(&&&x)=0 %then
在您的示例中,为了防止出现错误,您似乎可以执行以下操作(不要忘记%If%then语句的尾随分号):
%If &&&x^=%str() %then and a.&&&x >= b.min_lgd_driver_&k;
还有一些建议: