Sas 在PROC SQL中创建的宏变量是局部变量还是全局变量
当我写作时:Sas 在PROC SQL中创建的宏变量是局部变量还是全局变量,sas,sas-macro,Sas,Sas Macro,当我写作时: proc sql; select count(*) into :out from sashelp.cars; quit; 宏变量out是全局变量还是局部变量?这取决于您在何处定义此宏变量,如果您在宏程序中定义它,则它是局部宏变量,否则它是全局宏变量。这取决于。让我们组合一个测试宏,看看会发生什么 %macro test(); proc sql noprint; select count(*) into :x from sashelp.cars; quit; %put IN
proc sql;
select count(*) into :out from sashelp.cars;
quit;
宏变量
out
是全局变量还是局部变量?这取决于您在何处定义此宏变量,如果您在宏程序中定义它,则它是局部宏变量,否则它是全局宏变量。这取决于。让我们组合一个测试宏,看看会发生什么
%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()
宏填充了一个局部变量。它在宏外部不可用
之后,我们设置%,让x=2
使x
成为一个全局变量。然后我们执行%test()
宏,看到X
将其值保持在%test()
宏之外
因此,如果它全局存在,它将继续存在并被覆盖。如果它不在全球范围内存在,那么它将继续不在全球范围内存在。让我们看一下文档,以完整地回答这个问题 报告说: 使用INTO创建的宏变量遵循%LET语句的作用域规则。有关详细信息,请参见宏变量的作用域 所以,我们点击这个链接,然后找到和 第一页有一个漂亮的树形图,显示SAS在分配或创建宏变量时所做的决定,这可能足以理解这一点 第二页有一些很好的例子和解释: 当宏处理器执行可以创建宏变量的宏程序语句(如%LET语句)时,宏处理器会尝试更改现有宏变量的值,而不是创建新的宏变量。%GLOBAL和%LOCAL语句是例外 在那一页上有一些非常好的例子;不过,归结起来很简单。如果已有一个具有该名称的现有宏变量,它将为该宏变量赋值,无论该变量位于何处—无论如何,在当前宏的作用域树中。(因此,一个正在执行的宏有两个符号表可供查找:本地和全局。另一个宏调用的宏有三个符号表:本地、调用宏的本地和全局等。)
但是,有两个相关的例外情况:指定要使用的表时,使用
%local
或%global
。在%let
或select into
之前引用宏变量的语句中的任何一条都会导致以下语句设置特定版本(本地或全局),这样您就可以确保安全。示例代码不显示宏。因此,它只能是全球性的。但是,从这个问题来看,您是否理解SAS中本地宏变量和全局宏变量的含义还不清楚。宏作用域的规则与SQL select into相同:与普通的%let语句相同代码>和%put\u local\u代码>将显示它。回答得好。可能还值得一提的是%local
,因为如果%local x
是宏%test
定义的第一行,这也会影响结果。这只是答案的一半。您还应该提到%global
如何影响行为。这是错误的。如果宏程序将其定义为%global
,则它将是一个全局变量,而不是局部变量。但是OP在使用proc sql定义宏输出之前没有提到宏变量已首先定义为全局宏变量。OP所说的与此无关。按照你的回答,这说明了不正确的信息。所以,你设置了条件!?所以我打算编辑你的答案来“纠正”它,但它基本上是一个全新的/不同的答案,这似乎不是正确的处理方法。我建议你仔细看看乔的答案,这是最准确的,并仔细阅读提供的链接。然而,最后一段并不是真正的答案。%local
和%global
语句所做的是让您显式地创建一个宏变量作为local或global。然后,%let
将使用您在引用的说明中所述的现有宏变量。