2016-05-10 35 views
1

誰かがなぜそれが起こっているのか説明できますか? 私はDB内のオブジェクトの依存関係ツリーを見つけようとしています。 たとえば、view5はトップビュー4に座っているビューで、トップビュー1に座っているとします。 また、 view3上に座っていますview2上に座っていますview1。 だから、 私はview1のマクロを照会するとき、私はview4、view5、view2とview3を取得する必要があります。SAS:再帰マクロが無限ループに入ります

これはマクロです:

最初の繰り返しがうまく機能

%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.); 
、 私はオブジェクトが "( 'ditemp.depend_test2'、 'ditemp.depend_test3')" の形でトップdepend_test1 に座ってもらいます は、私は夫婦の問題を参照してください...のみが止まることはありません

+1

これはツリーのトラバーサルの問題だと思います。最近、SAS-L listservで、ハッシュ・ソリューションを使って尋ねられました。 – Reeza

+1

https://gist.github.com/statgeek/14e3aa2a9f718f551cd98134e9ceed30これも問題は解決するかもしれませんが、マクロの問題は解決しないかもしれません。 – Reeza

答えて

2

を、私は、変数dependent_objectname(ゼロより大きい) の長さをチェックすることだし、再びマクロを呼び出す、 。

声明:

%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.) ; 
+0

あなたのご意見ありがとうございます。これを修正して今すぐ動作します! – user2518751

+0

ニースの回答 - これは受け入れられたとは言えませんでした。トムの答えが解決策を提供する一方、この答えは実際に元のコードの問題に対処して修正します。 –

2

あなたは再帰を破るために、あなたのテストで自動変数SQLOBSを使用することができます依存のリストを生成するために、SQLクエリを使用しているので。

%if &sqlobs %then %do; 
    %dependencies(obj = &dependent_objectname.); 
%end; 

はまたませは、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'); 
+0

大変ありがとうございました – user2518751

関連する問題