2015-11-15 32 views
3

當我寫:是否在PROC SQL創建的宏變量成爲局部或全局

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

請問宏變量out成爲一個全球性或局部變量?

+2

您的示例代碼不顯示宏。因此它只能是全球性的。但是從這個問題來看,你是否清楚SAS是否理解了本地vs全球宏觀變量的含義。宏定義的規則與SQL選擇的規則相同:因爲它們使用簡單的%let語句。 – Quentin

+0

做一個'%put _global_;'和'%put _local_;'會顯示它。 – Snorex

回答

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()宏之外。

因此,如果全局存在,它將繼續存在並被覆蓋。如果它不在全球範圍內,它仍然不存在於全球。

+0

很好的答案。它也可能值得一提的是'%local',因爲如果'%local x;'是宏'%test'定義中的第一行,那麼這也會影響結果。 – Amir

+0

這只是答案的一半。你還應該提及'%global'如何影響行爲。 –

-1

這取決於你在哪裏定義這個marco變量,如果你在宏程序中定義它,它是一個本地宏變量,否則它是一個全局宏變量。

+1

這是錯誤的。如果你的宏程序將其定義爲'%global',那麼它將是一個全局變量,而不是本地變量。 –

+0

但是OP在使用proc sql來定義宏輸出之前沒有提到宏變量已經被定義爲全局宏變量。 –

+0

這與OP說的無關。正如你的回答所表達的那樣,它說明了不正確的信息。 –

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。另一個宏調用的宏有三個:local,本地調用宏和global。)

然而,還有一對相關的例外:當您指定的表使用,具有%local%global。在您的%letselect into之前引用宏變量的任何語句都將導致以下任何語句設置該特定版本 - 本地或全局 - 然後您確定無疑是安全的。

+0

最後一段並不是真的。 '%local'和'%global'語句的作用是讓你明確地創建一個宏變量作爲本地或全局變量。然後,'%let'將使用現有的宏變量,如您在引用的解釋中所述。 – Tom