2017-05-17 85 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