使用文件中的代码作为 SAS 宏变量的内容

Posted

技术标签:

【中文标题】使用文件中的代码作为 SAS 宏变量的内容【英文标题】:Use code in a file as content of a SAS macro variable 【发布时间】:2015-05-22 17:02:20 【问题描述】:

我有一系列文件,每个文件都包含 SQL 代码。 我想使用 SAS 使用该 SQL 运行直通查询。 由于这些文件经常变化,我只想要一种自动化的方式来保持 SAS 与这些文件同步。 我在想,如果我可以导入 SQL 文件并将其放入宏变量中,那么我可以在我的 SAS 直通中使用该宏,并且一切都会同步。 但除了 SAS 数据集,我不知道如何读取外部 SQL,这从一开始就没有多大意义...... 例子: sqlcode.sql

select *
from table1

在 SAS 中:

/*Somehow read sqlcode.sql into a macro variable sassql*/

proc sql;
connect to netezza (SERVER=MYSERVER DATABASE=MYDBS);

execute (
&sassql.

) by netezza;

;
quit; 

【问题讨论】:

【参考方案1】:

EDIT-实际有效的新答案:

您可以通过数据步骤将整个查询读入宏变量,但查询中的总字符数限制为 32,767 个,因为这是字符变量最多可以容纳的。

我建议使用数据步骤逐行读取您的查询,将整个查询放入临时文件,并使用%include 包含临时文件:

filename query temp;
data _null_;
  infile 'C:\My Documents\sql query.sql' end=eof truncover;
  input @1 line $32767.;
  file query;
  if _n_=1 then put  'proc sql;
                      connect to netezza (SERVER=MYSERVER DATABASE=MYDBS);
                      execute (';
  put                 line;
  if eof then put    ') by netezza;
                      quit;';
run;
%include query / source2;
filename query clear;

这里,临时文件为“查询”,数据步骤逐行读取sql文件,并将每一行输出到临时文件中。

【讨论】:

%include 用于运行外部 SAS 代码,在这种情况下不起作用。至少,我无法让它工作。 @ADJ 你说得对,我最初的答案没有奏效,因为它将%include... 传递给数据库。上面更新的答案应该可以工作。 实际上,您并没有将%include 传递给数据库 - 并非如此。您可以在该上下文中使用 SAS 宏变量,它工作正常。 %include 对它的工作时间非常挑剔,出于某种原因可能与 1970 年代的大型机有关。【参考方案2】:

用 datasteps 读入你的文件,然后用这样的 sql select-into 查询跟进这些文件:

data query_text;
    infile 'sql query.sql';
    input line $1000;
run;

proc sql;
    select * from query_text into :sassql separated by ' ';
quit;

整个读入的文件将被转储到一个宏变量中。

【讨论】:

【参考方案3】:

我曾多次遇到此问题,因此我编写了自己的 %include 宏版本,名为 %include_file()。查看我的笔记,它应该可以工作,但如果您包含的文件包含宏标记,您可能需要调整宏引用功能。

它适用于任何大小的文件(因为它一次读取一行并且不会尝试将整个文件存储到变量中)。

简单地这样称呼它:

proc sql;
connect to netezza (SERVER=MYSERVER DATABASE=MYDBS);
execute (
  %include_file(iFileName=c:\mypath\mysasfile.sas);
) by netezza;
;
quit; 

代码如下。我建议把它放在你的宏自动调用库中:

%macro include_file(iFileName=);
  %local filrf rc fid rc2;

  %let filrf=myfile2;

  %let rc=%sysfunc(filename(filrf, &iFileName, , lrecl=32767));
  %let fid=%sysfunc(fopen(&filrf,i,32767,b));

  %if &fid > 0 %then %do;
    %let rc = %sysfunc(fread(&fid));
    %do %while(&rc eq 0);  
      /* NOTE THE STACKED COMMANDS BECAUSE WE ARE RETURNING THE CONTENTS OF MACRO VAR C HERE AND DONT WANT WHITESPACE */
      %let rc2=%sysfunc(fget(&fid,c,32767));%quote(&c)%let rc = %sysfunc(fread(&fid)); 
    %end;
  %end;
  %else %do;
    %put C &fid %sysfunc(sysmsg());
  %end;
  %let rc=%sysfunc(fclose(&fid));
  %let rc=%sysfunc(filename(filrf));
%mend;

【讨论】:

以上是关于使用文件中的代码作为 SAS 宏变量的内容的主要内容,如果未能解决你的问题,请参考以下文章

在宏内部使用变量内部数据集名称时,SAS语法错误22和200

伪代码转换为SAS宏代码

SAS Proc Datasets - 使用宏变量更改数据集名称

SAS中的宏变量开头和结尾分别是啥命令?

SAS:包括输出中的宏参考? [重复]

SAS中的粘滞宏变量