有人可以解释为什么会这样吗? 我试图在数据库中查找对象依赖关系树。 让我们说view5是坐在顶视图4上的视图,它位于顶视图1上。 也, view3坐在顶部view2坐在顶部view1。 所以, 当我查询view1的宏时,我应该返回view4,view5,view2和view3。
这是宏:
%macro dependencies(obj=);
%let dependent_objectname =;
proc sql noprint;
select "'"||trim(dependent_objectname)||"'"
into :dependent_objectname separated by ", "
from &_input.
where src_objectname in (&obj.);
quit;
%put &dependent_objectname.;
%let dependent_objectname = (&dependent_objectname.);
%put &dependent_objectname.;
%if %length("&dependent_objectname")>0 %then
%dependencies(obj = &dependent_objectname.);
%mend dependencies;
%let source = 'ditemp.depend_test1';
%put &source.;
%dependencies(obj = &source.);
第一次迭代效果很好, 我让对象坐在上面depend_test1 以"(' ditemp.depend_test2',' ditemp.depend_test3')"的形式 然后我检查变量dependent_objectname的长度(大于零) 并再次调用宏, 只有它永远不会停止...
答案 0 :(得分:2)
我看到了几个问题。
声明:
%if %length("&dependent_objectname")>0 %then %do;
即使& dependent_objectname的值为null,也将始终返回true。因为引号是宏语言中值的一部分。你可能想要:
%if %length(&dependent_objectname)>0 %then %do;
对于零度的测试通常有效。或者参见本文以获得更好的方法。 http://support.sas.com/resources/papers/proceedings09/022-2009.pdf
在此之前,声明:
%let dependent_objectname = (&dependent_objectname.);
正在为您的值添加括号。所以,即使& dependent_objectname为null,在此之后也是()。看起来你不需要这些括号,所以我会跳过这句话。
我还想补充一下:
%local dependent_objectname ;
到宏的顶部。这样,每次调用宏都会有自己的本地宏变量,而不是让它们全部使用第一次迭代中创建的宏变量(或者更糟糕的是,都使用全局宏变量)。
您已明智地添加%PUT语句以帮助调试。我希望他们会证明& dependent_objectname的值总是非当前写的非null。您还可以添加:
%put The length is: %length(&dependent_objectname.) ;
答案 1 :(得分:2)
由于您使用SQL查询生成依赖列表,因此可以在测试中使用自动变量SQLOBS
来中断递归。
%if &sqlobs %then %do;
%dependencies(obj = &dependent_objectname.);
%end;
另外 NOT 使用逗号作为OBJ参数中列出的项之间的分隔符。 SAS中的IN
运算符不需要它们,它们会在宏调用中造成麻烦。
select * from sashelp.class where name in ('Alfred' 'Alice') ;
所以你的宏看起来像这样:
%macro dependencies(object_list);
%local dependent_list ;
proc sql noprint;
select catq('1as',dependent_objectname)
into :dependent_list separated by ' '
from &_input.
where src_objectname in (&object_list)
and dependent_objectname is not null
;
quit;
%put Dependent Objects of (&object_list) = (&dependent_list);
%if &sqlobs %then %dependencies(&dependent_list);
%mend dependencies;
这是一个测试用例。
%let _input=sample;
data sample;
length src_objectname dependent_objectname $41 ;
input (_all_) (:) ;
cards;
object1 object2
object2 object3
object2 object4
;;;;
%dependencies('object1');