简体   繁体   中英

SAS - A Macro following a proc sql called in a macro

New here, so if I did something wrong, I apologize. I'm new user of SAS as well.

I created a macro that calls first a proc sql that creates a certain table that I want to pass it to another macro (inside the first macro).

%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;

The Mc_Obsnvars macro use the attrn function to get the number of observations from the given dataset (it opens the dataset first). Depending on the number of observations, my program either use the sqlloader or not. OR_IN and OR_OUT are libnames (oracle engine).

When The macro Mc_Copy_Table is executed, with let's say TABLE1 as argument, the Mc_Obsnvars is executed first which tries to open TABLE1 which doesn't exist yet. The proc sql is executed afterwards.

Why the macro is executed before the proc sql ? and is there any way to have the proc sql be executed first ? putting the proc sql part in a macro doesn't solve the problem. Thanks :)

I think you have a syntax issue, as Quentin alludes to in his comment. This works OK for me:

%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);

Note however, you don't have to do the count. There is an automatic variable from PROC SQL called &sqlobs with the number of records returned from the last query.

So this gives you what you are looking for, I think:

%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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM