SAS宏执行顺序

时间:2018-02-23 06:35:43

标签: sas sas-macro

我使用宏来锁定数据集:

%macro lockTab(member=APP_DATABASE,timeout=30,retry=500);
  %global LOCK_&member;
  %let LOCK_&member = ;
  %local starttime;
  %let starttime = %sysfunc(datetime());
  %put try to lock &member.: &starttime;
  %do %until (&syslckrc = 0
       or %sysevalf(%sysfunc(datetime()) > (&starttime + &timeout)));
      lock APPLIB.&member.;
      %put syslckrc=&syslckrc;
      %if &syslckrc > 0 %then %let rc=%sysfunc(sleep(&retry.));
  %end;
  %let endtime = %sysfunc(datetime());
  %put end of try to lock &member.: &endtime;
  %if &syslckrc <= 0 %then %do;
      %let LOCK_&member = LOCK;
  %end;
  %else %do;
    %let _appRetcode = 12;
    %let _appErrtext = Database is locked.;
  %end;
    %put ende Locktab: appretcode: &_appRetcode;
    %put ende Locktab: syslckrc: &syslckrc;
%mend;

这是我使用宏的代码(_appRetcode是一个全局变量), 宏微调器只是在网页上显示加载微调器的datastep。 然后锁定数据集并输出在lockTab中设置的_appRetcode。 %debug打印出所有带范围的宏变量。

%spinner(show)

%lockTab

%put EYECATCHER &_appRetcode;

%debug(DUMP Variablen nach LOCKTAB)

这是我的SASlog:

NOTE: 1 record was written to the file _WEBOUT.
      The minimum record length was 42.
      The maximum record length was 42.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


SYMBOLGEN:  Macro variable _APPRETCODE resolves to 0
EYECATCHER 0
SYMBOLGEN:  Macro variable MEMBER resolves to APP_DATABASE
SYMBOLGEN:  Macro variable MEMBER resolves to APP_DATABASE
SYMBOLGEN:  Macro variable MEMBER resolves to APP_DATABASE
                                                                                          The SAS System

SYMBOLGEN:  Macro variable STARTTIME resolves to 1834989255.00056
try to lock APP_DATABASE: 1834989255.00056
SYMBOLGEN:  Macro variable MEMBER resolves to APP_DATABASE
ERROR: A lock is not available for APPLIB.APP_DATABASE.DATA.
ERROR: Lock held by process 1360575.
SYMBOLGEN:  Macro variable SYSLCKRC resolves to 70031
syslckrc=70031
SYMBOLGEN:  Macro variable SYSLCKRC resolves to 70031
SYMBOLGEN:  Macro variable RETRY resolves to 500
SYMBOLGEN:  Macro variable SYSLCKRC resolves to 70031
SYMBOLGEN:  Macro variable STARTTIME resolves to 1834989255.00056
SYMBOLGEN:  Macro variable TIMEOUT resolves to 30
SYMBOLGEN:  Macro variable MEMBER resolves to APP_DATABASE
ERROR: A lock is not available for APPLIB.APP_DATABASE.DATA.
ERROR: Lock held by process 1360575.
.......
end of try to lock APP_DATABASE: 1834989285.01467
SYMBOLGEN:  Macro variable SYSLCKRC resolves to 70031
SYMBOLGEN:  Macro variable _APPRETCODE resolves to 12
ende Locktab: appretcode: 12
                                                                                          The SAS System

SYMBOLGEN:  Macro variable SYSLCKRC resolves to 70031
ende Locktab: syslckrc: 70031

为什么在输出我的宏之前打印出EYECATCHER?

我预计首先输出宏lockTab,然后是“EYECATCHER 12”。 ?????

%debug给出:(范围/变量/值)GLOBAL / _APPRETCODE / 12

3 个答案:

答案 0 :(得分:1)

我认为问题与解析器决定宏调用何时结束有关。如果使用参数定义宏(甚至是参数的空列表),则宏调用不会在空白处结束。它以右括号结束。它也将以SAS语言标记(包括SAS语言分号)或另一个宏调用结束。

这就是为什么像下面这样丑陋的东西会起作用的原因:

%macro doit (x=) ;
  %put &=x  ;
%mend doit;
%doit     (x=3)

更改@ Allan的示例,如果demo1和demo2的定义没有参数,则代码可以正常工作,因为demo1和demo3的调用将由空格触发。

358  %macro demo1; %put 1 first; %mend;
359  %macro demo3; %put 3 third; %mend;
360  %macro x;
361    %demo1
362    %put 2 second;
363    %demo3
364  %mend x;
365  %x
1 first
2 second
3 third

但是如果使用参数列表定义%demo1,则空格不足以结束宏调用。甚至%PUT语句也不会结束宏调用。 SAS一直在寻找参数列表,直到它到达%demo3的调用,并且实现&#34;以及必须完成第一次宏调用。&#34;到那时,%PUT语句已经执行。

366  %macro demo1(); %put 1 first; %mend;
367  %macro demo3; %put 3 third; %mend;
368  %macro x;
369    %demo1
370    %put 2 second;
371    %demo3
372  %mend x;
373  %x
2 second
1 first
3 third

作为证据,请在下面考虑。看起来我将VAR参数传递给%X(没有定义参数)。但是%demo1的调用仍然在等待参数列表,它接受了它。这表明%PUT语句不足以结束%demo1的调用。

404  %macro demo1(var=); %put 1 first; %put &=var ;%mend;
405  %macro x;
406    %demo1
407    %put 2 second;
408  %mend x;
409  %x(var=hello)
2 second
1 first
VAR=hello

我很难记住伊恩·惠特洛克教给我的所有规则,有时候害怕把一个人归咎于我,我记得不正确。但我非常有信心他相信所有的宏应该至少有一个参数(他对宏的定义是参数化的代码单元&#39;),并且宏调用应该始终以括号结束,甚至如果它是接受默认值的参数的空列表,即%doit()。这可以确保宏在预期时执行,而无需添加SAS语言分号,这有时可能会破坏。

答案 1 :(得分:0)

只是一个想法: 您是否尝试过宏调用后加分号?缺少分号通常会带来一些问题。即使宏似乎运行正常。

答案 2 :(得分:0)

您提供的代码是否包含在父宏中?

我能够重现此行为,但仅限于另一个宏。

示例代码:

%macro x;
  %macro demo1(); %put see;  %mend;
  %macro demo2(); %put this; %mend;
  %demo1          %put here; %demo2()
%mend;
%x

打印:

here  
see
this

对比:

%macro demo1(); %put see;  %mend;
%macro demo2(); %put this; %mend;
%demo1          %put here; %demo2()

打印哪些:

see  
here
this

这确实似乎是一个解析器错误,或者至少是 - 一种不一致。

我建议将子宏定义移到父包装器之外。我还建议始终使用括号定义宏,并按原样调用它们。