重写/追加sas变量


%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变量为空,则只添加带有columnID数据的tr和td。如果rows变量不为空,则追加它。但它只提供了表的最后一条记录。

假设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.;

将返回

"""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 $32767;
rows = cats(rows,"<tr><td>",ColID,"</td></tr>");
if eof then output;
run;

如果您要使用call execute,例如,如果您计划将其put到一个HTML页面(例如,在存储过程中),其中包含您想要执行的一些包装器代码,if _n_=1表示开始,if eof表示结束,您通常会这样做。

最新更新