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

Use code in a file as content of a SAS macro variable

我有一系列文件,每个文件都包含 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; 

实际有效的编辑新答案:

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

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

包含临时文件
filename query temp;
data _null_;
  infile 'C:\My Documents\sql query.sql' end=eof truncover;
  input @1 line 767.;
  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;

这里,临时文件是"query",数据步骤逐行读取sql文件,并将每一行输出到临时文件。

使用数据步骤读入您的文件,然后使用 sql select 跟进这些文件,进入如下查询:

data query_text;
    infile 'sql query.sql';
    input line 00;
run;

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

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

我已经 运行 解决过这个问题几次,所以我编写了自己的 %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;