2017-05-17 102 views
0

這裏是新的,所以如果我做錯了,我很抱歉。我也是SAS的新用戶。SAS - 一個宏,在宏中調用一個proc sql

我創建了一個宏,它首先調用一個proc sql,創建一個我想將它傳遞給另一個宏(在第一個宏內部)的特定表。

%Macro Mc_Copy_Table (TABLE_NAME); 
    proc sql; 
    create table &TABLE_NAME as 
    select * 
    from OR_IN.&TABLE_NAME; 

    connect using OR_OUT; 
    execute (truncate table &TABLE_NAME) By OR_OUT; 
    disconnect from OR_OUT; 
    quit; 

    %MC_obsnvars(&TABLE_NAME); 

    %put &Nobs; 
    %if &Nobs > 100000 %then 
    %do; /* use of the sql loader */ 
    proc append base = OR_OU. &TABLE_NAME (&BULKLOAD_OPTION) 
       data = &TABLE_NAME; 
    run; 
    %end; 
    %else 
    %do; 
    proc append base = OR_OU. &TABLE_NAME (Insertbuff=10000) 
       data = &TABLE_NAME; 
    run; 
    %end; 
%Mend Mc_Copy_Table; 

的Mc_Obsnvars宏使用attrn函數來獲取從給定數據集的觀測數(它首先打開數據集)。根據觀察次數,我的程序要麼使用sqlloader,要麼不使用sqlloader。 OR_IN和OR_OUT是libnames(oracle引擎)。

當執行宏Mc_Copy_Table時,我們假設TABLE1爲參數,首先執行Mc_Obsnvars,嘗試打開尚不存在的TABLE1。之後執行proc sql。

爲什麼宏在proc sql之前執行?有什麼辦法可以先執行proc sql?將proc sql部分放入宏中並不能解決問題。謝謝:)

+0

如果我明白你的問題,你要第一時間執行PROC SQL就計算觀測數。如果這是正確的,則不需要兩個宏。請刪除%Mc_Obsnvars(&TABLE_NAME)並運行您的代碼。 –

+1

在宏調用之前是否有分號結束'create table'語句?如果不是,那麼%Mc_Obsnvars()將在執行'create table'之前執行。你的PROC SQL步驟在哪裏結束?另外,是%Mc_Obsnavars()生成任何SAS代碼,還是它只是填充一個宏變量? – Quentin

+0

我編輯了代碼,使其更清晰。謝謝你的回覆。 – Spoutnik

回答

1

我覺得你有一個語法問題,因爲Quentin在他的評論中暗示。這適用於我:

%macro copy_table(intable, outtable); 
proc sql noprint; 
create table &outtable as 
select * from &intable; 

%count_obs(&outtable); 
%put NOBS:&nobs; 
quit; 
%mend; 

%macro count_obs(table); 
%global nobs; 
select count(*) into :nobs trimmed from &table; 
%mend; 

data test; 
do i=1 to 10; 
    output; 
end; 
run; 

%copy_table(test,test2); 

但是請注意,您不必進行計數。 PROC SQL有一個名爲&sqlobs的自動變量,以及最後一次查詢返回的記錄數。

所以這個給你,你在找什麼,我想:

%macro copy_table(intable, outtable); 
proc sql noprint; 
create table &outtable as 
select * from &intable 
where i < 5; 

%let nobs=&sqlobs; 
%put NOBS:&nobs; 
quit; 
%mend; 
%copy_table(test,test2); 
+0

感謝和''sqlobs'技巧。我編輯了我的問題(並替換了代碼部分)。除了日誌告訴我Work.TABLE1(我創建的表)不存在(因爲它在執行'proc sql'之前執行宏'%Mc_Obsnvars(&TABLE_NAME)')之外沒有任何錯誤。在這裏,我有'proc sql'之外的宏調用,所以在quit語句之後。順便說一句,在'proc sql'內部或外部進行宏調用有什麼區別嗎? – Spoutnik

+0

我試圖在'proc sql'外面使用'%let Nobs =&sqlobs;',它總是給我0(當我使用宏'%MC_obsnvars(&TABLE_NAME);'時,它也一樣)。很奇怪。我注意到當我重新提交代碼時,會執行使用sqlloader的'proc append'(因爲工作表現在已經存在,但它不是解決方案)。 – Spoutnik

+0

如果你仍然在爲此付出努力,請設置'options notes mprint mlogic symbolgen;',運行代碼並將相關日誌部分粘貼到問題中。 – DomPazz