【问题标题】:SAS - A Macro following a proc sql called in a macroSAS - 在宏中调用的 proc sql 之后的宏
【发布时间】:2017-05-17 15:50:50
【问题描述】:

这里是新人,所以如果我做错了什么,我深表歉意。我也是SAS的新用户。

我创建了一个宏,它首先调用一个 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,要么不使用。 OR_IN 和 OR_OUT 是 libnames(oracle 引擎)。

当执行宏 Mc_Copy_Table 时,假设 TABLE1 作为参数,首先执行 Mc_Obsnvars,它尝试打开尚不存在的 TABLE1。 proc sql 之后执行。

为什么宏在 proc sql 之前执行?有没有办法让proc sql首先执行?将proc sql 部分放在宏中并不能解决问题。谢谢:)

【问题讨论】:

  • 如果我理解你的问题,你想先执行 Proc Sql 然后计算观察次数。如果这是正确的,则不需要两个宏。请删除 %Mc_Obsnvars(&TABLE_NAME) 并运行您的代码。
  • 在您的宏调用之前是否有一个分号来结束create table 语句?如果没有,则 %Mc_Obsnvars() 将在执行 create table 之前执行。您的 PROC SQL 步骤在哪里结束?另外,%Mc_Obsnavars() 是生成任何 SAS 代码,还是只是填充宏变量?
  • 我编辑了代码以使其更清晰。感谢您的回复。

标签: macros sas sas-macro


【解决方案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);

【讨论】:

  • 感谢&amp;sqlobs 技巧。我编辑了我的问题(并替换了代码部分)。没有错误,除了日志告诉我 Work.TABLE1(我创建的表)不存在(因为它在执行 proc sql 之前执行宏 %Mc_Obsnvars(&amp;TABLE_NAME))。这里我在proc sql 之外有宏调用,所以在退出语句之后。顺便说一句,在 proc sql 内部或外部调用宏有什么区别?
  • 我尝试在外部使用%let Nobs=&amp;sqlobs;,也在proc sql 内部使用,它总是给我0(当我使用宏%MC_obsnvars(&amp;TABLE_NAME); 时也是如此)。很奇怪。我注意到当我重新提交代码时,使用sqlloader的proc append被执行(因为工作表现在已经存在,但不是解决方案)。
  • 如果你还在纠结这个问题,设置options notes mprint mlogic symbolgen;,运行代码,将相关日志部分粘贴到问题中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多