Overwriting/Appending sas 变量

Overwriting/Appending sas variable

%let rows = "";

%macro test;

 proc sql noprint;
   select count(ID)
   into: sqlRows
   from mytbl;
 quit;

 %do i = 1 %to &sqlRows; * loop from 1 to sqlRows;

   proc sql noprint;
     select ID
     into: ColumnID
     from mytbl(firstobs= &i);
   quit;

   %if &rows eq "" %then %do
     %let rows = "<tr><td>&ColumnID</td></tr>";
   %end;

   %if &rows ne "" %then %do
     %let rows = "&rows<tr><td>&ColumnID</td></tr>";
   %end;

 %end;*End loop;

%mend;

%test;

%put &rows;

您好,我想将 mytbl 的列 ID 数据的所有数据放入一个变量中。

我创建了一个名为 rows 的变量并在其中分配了空值。然后使用循环我一个一个地获取 mytab 的值并将它们保存在 columnID 变量中。如果 rows 变量为空,则只添加 tr 和 td 以及 columnID 数据。如果 rows 变量不为空,则追加它。但它只给我 table.

的最后一条记录

假设 mytbl 在 ID 列中有数据 1,2 和 3

rows 变量的数据应为

   <tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</td></tr>

但它只显示最后一行的数据为

<tr><td>3</td></tr>

您遇到了几个不同的问题,首先是缺少分号。更重要的是,您的代码比它需要的更复杂。您可以使用 SELECT INTO: 通过一个 PROC SQL 步骤获得您想要的结果,您不需要为每条记录单独执行一个 PROC SQL 步骤。玩转:

data have;
  do ID=1 to 3;
    output;
  end;
run;

proc sql noprint;
  select cats('<tr><td>',ID,'</td></tr>') 
    into :Rows
    separated by ""
  from have;
quit;

%put &rows;

我认为您严重误解了什么是 SAS 中的宏变量,而不是常规变量。你没有确切地说出你最终要用它做什么,但是尽管如此。

首先,宏变量不带引号;如果它们包含它们,它们将被视为常规字符。所以:

%let var = "";
%let var = "&var.123";
%put &=var.;

将return

"""123"

因为它不太了解引号(有点 知道它们,但它不像普通 SAS 变量那样对待它们) .

其次,正如 Quentin 正确指出的那样,您到底为什么要使用 SQL 一次连续进行?这基本上与您使用 SQL 的原因相反。 SQL 非常适合一次对整个数据集做某事,一次只处理一行绝对是可怕的——这就是数据步骤的目的。

如果你真的想要一个 SAS 变量,或者你想一次处理一行,你应该只使用数据步骤:

data want;
  set mytbl end=eof;
  retain rows;  *do not need to initialize to missing, that is normal;
  length rows 767;
  rows = cats(rows,"<tr><td>",ColID,"</td></tr>");
  if eof then output;
run;

如果你打算使用 call execute,你通常会这样做,例如,如果你计划 put 这个到 HTML 页面(例如在存储过程中) 和一些你想执行的包装代码,在 if _n_=1 中作为开始,在 if eof 中作为结束。