在PROC SQL中创建的宏变量是本地变量还是全局变量

时间:2015-11-15 23:15:32

标签: sas sas-macro

当我写:

proc sql;
    select count(*) into :out from sashelp.cars;
quit;

宏变量out是否成为全局或局部变量?

3 个答案:

答案 0 :(得分:8)

这取决于。让我们整理一个测试宏,看看会发生什么

%macro test();
proc sql noprint;
select count(*) into :x from sashelp.cars;
quit;
%put IN MACRO: &x;
%mend;

options nosource nonotes;

%symdel x;

%test();

%put Out MACRO: &x;

%let x=2;

%put Out MACRO: &x;

%test();

%put Out MACRO: &x;

创建:

IN MACRO:      428
WARNING: Apparent symbolic reference X not resolved.
Out MACRO: &x
Out MACRO: 2
IN MACRO:      428
Out MACRO:      428

所以在开始时,没有X宏变量。 %test()宏填充了一个局部变量。它不在宏之外。

之后,我们设置%let x=2使X成为全局变量。然后我们执行%test()宏,看看X将其值保留在%test()宏之外。

因此,如果它全局存在,它将继续存在并被覆盖。如果它不是全球存在的,它将继续不存在于全球范围内。

答案 1 :(得分:2)

让我们看一下文档来强制回答这个问题。

documentation for SQL INTO clause in the Macro language dictionary说:

  

使用INTO创建的宏变量遵循%LET语句的作用域规则。有关更多信息,请参阅宏变量的范围。

因此,我们点击该链接,然后找到this page - How Macro Variables are Assigned and Resolvedthis page - Examples of Macro Variable Scopes

第一页有一个漂亮的树形图,显示SAS在分配或创建宏变量时所做的决定,这可能足以理解这一点。

第二页有一些很好的例子和解释:

  

当宏处理器执行可以创建宏变量的宏程序语句(例如%LET语句)时,宏处理器会尝试更改现有宏变量的值,而不是创建新的宏变量。 %GLOBAL和%LOCAL语句是例外。

该页面上有一些非常好的例子;然而,它归结为简单。如果已存在具有该名称的现有宏变量,则无论如何,它都会将该值分配给该宏变量,无论该变量位于当前宏的作用域树中。 (因此,一个宏执行有两个符号表来查看:本地和全局。另一个宏调用的宏有三个:本地,调用宏本地,以及全局。等等。)

但是,有一对相关的例外:指定要使用的表格时,使用%local%global。在%letselect into之前引用宏变量的任何一个语句都会导致以下任何语句设置该特定版本(本地或全局),然后您确定安全。

答案 2 :(得分:-1)

这取决于你定义这个marco变量的位置,如果你在宏程序中定义它,它是一个局部宏变量,否则它是一个全局宏变量。