我收到以下警告 - >
error of multiple tables can't be assigned '.'
下面是我的代码我试图从库中获取某些列变量,然后检查变量值是否丢失。但是有上述错误。
请有人帮我弄清楚原因吗?
%macro drop_check(dsn1=,lib2=,dsn=);
%local rc dsid result;
proc sql noprint;
select distinct catx(".",libname,memname), name into :list2, :varname separated by " "
from dictionary.columns
where libname = upcase("&lib2") and format =('YYMMDD10.');
quit;
%put &list2;
data &dsn(keep=&varname);
set &list2;
&varname=.;
run;
%MEND drop_check;
%drop_check(dsn1=sample,lib2=grp,dsn=er2);
答案 0 :(得分:0)
错误的直接原因是VARNUM()
不接受变量名称列表,但这就是您正在使用的名称。 &VARNAME
是SQL查询中变量名的列表。
另一个重要问题:SELECT ... INTO
未捕获整个数据集名称列表,因为SEPARATED BY
指令仅适用于:varname
。
因此,您的DATA步骤不会连接所有数据集,只是第一个数据集。您还需要将SEPARATED BY
添加到第一个宏变量中。
最重要的是,我不明白你想做什么。如果您想知道库中存在哪种具有该格式的列,那么您已经拥有该列,因为SQL查询列出了具有该格式的所有数据集和列。
所以我发布了更正的PROC SQL代码。并且您知道为什么发生了VARNUM()
错误。也许你可以从那里拿走它。
如果你确切地澄清了你想要完成的事情,我相信我们可以进一步提供帮助。
proc sql noprint;
select distinct catx(".",libname,memname), name into :list2 separated by " ", :varname separated by " "
from dictionary.columns
where libname = upcase("&lib2") and format =('YYMMDD10.');
quit;
[新增2016-12-13]
好的,我猜猜以下会做你想做的事。你可以修改它来做其他事情。
有很多方法可以实现这一目标,我只选了一个。在这种情况下,CALL EXECUTE()
只是作为代码生成器,但它也能够解析宏和宏变量。如果您熟悉JavaScript,则与document.write()
类似,因为我使用它。
从SQL字典创建工作表而不是尝试使用宏列表似乎相当有效。在大多数情况下,字典不会大到足以成为问题,尤其是在仅选择具有使用特定格式的变量的数据集时。
我假设您真正想要的是在各个数据集中将值设置为缺失,因此本示例为每个具有指定格式的变量的数据集生成DATA
步骤。如果要永久保留它们,可以将它们复制回原始库。
%macro drop_check(lib2,format=YYMMDD10.);
proc sql noprint;
create table vars as
select distinct libname, memname, name as varname
from dictionary.columns
where libname = upcase("&lib2") and format="&format"
order by libname, memname;
quit;
data _null_;
set vars;
by libname memname;
if first.memname
then do;
call execute("data " || memname || ";");
call execute(" set " || strip(libname) || "." || strip(memname) || ";");
end;
call execute(varname || "=.;");
if last.memname
then call execute("run;");
run;
%MEND drop_check;
options mprint symbolgen;
%drop_check(sashelp,format=DATETIME.)
上面的调用,使用SASHELP库并查找DATETIME。格式,产生了以下结果。我确认变量设置为缺失。
MPRINT(DROP_CHECK): proc sql noprint;
SYMBOLGEN: Macro variable LIB2 resolves to sashelp
SYMBOLGEN: Macro variable FORMAT resolves to DATETIME.
MPRINT(DROP_CHECK): create table vars as select distinct libname, memname, name as varname
from dictionary.columns where libname = upcase("sashelp") and format="DATETIME." order by
libname, memname;
NOTE: Table WORK.VARS created, with 6 rows and 3 columns.
MPRINT(DROP_CHECK): quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.07 seconds
cpu time 0.07 seconds
MPRINT(DROP_CHECK): data _null_;
MPRINT(DROP_CHECK): set vars;
MPRINT(DROP_CHECK): by libname memname;
MPRINT(DROP_CHECK): if first.memname then do;
MPRINT(DROP_CHECK): call execute("data " || memname || ";");
MPRINT(DROP_CHECK): call execute(" set " || strip(libname) || "." || strip(memname) || ";");
MPRINT(DROP_CHECK): end;
MPRINT(DROP_CHECK): call execute(varname || "=.;");
MPRINT(DROP_CHECK): if last.memname then call execute("run;");
MPRINT(DROP_CHECK): run;
MPRINT(DROP_CHECK): data VCATALG ;
MPRINT(DROP_CHECK): set SASHELP.VCATALG;
MPRINT(DROP_CHECK): created =.;
MPRINT(DROP_CHECK): modified =.;
MPRINT(DROP_CHECK): run;
MPRINT(DROP_CHECK): data VEXTFL ;
MPRINT(DROP_CHECK): set SASHELP.VEXTFL;
MPRINT(DROP_CHECK): modate =.;
MPRINT(DROP_CHECK): run;
MPRINT(DROP_CHECK): data VSTYLE ;
MPRINT(DROP_CHECK): set SASHELP.VSTYLE;
MPRINT(DROP_CHECK): crdate =.;
MPRINT(DROP_CHECK): run;
MPRINT(DROP_CHECK): data VTABLE ;
MPRINT(DROP_CHECK): set SASHELP.VTABLE;
MPRINT(DROP_CHECK): crdate =.;
MPRINT(DROP_CHECK): modate =.;
MPRINT(DROP_CHECK): run;
NOTE: There were 6 observations read from the data set WORK.VARS.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
NOTE: CALL EXECUTE generated line.
1 + data VCATALG ;
2 + set SASHELP.VCATALG;
3 + created =.;
4 + modified =.;
5 + run;
NOTE: There were 17212 observations read from the data set SASHELP.VCATALG.
NOTE: The data set WORK.VCATALG has 17212 observations and 10 variables.
NOTE: DATA statement used (Total process time):
real time 0.15 seconds
cpu time 0.14 seconds
6 + data VEXTFL ;
7 + set SASHELP.VEXTFL;
8 + modate =.;
9 + run;
NOTE: There were 21 observations read from the data set SASHELP.VEXTFL.
NOTE: The data set WORK.VEXTFL has 21 observations and 9 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
10 + data VSTYLE ;
11 + set SASHELP.VSTYLE;
12 + crdate =.;
13 + run;
NOTE: There were 54 observations read from the data set SASHELP.VSTYLE.
NOTE: The data set WORK.VSTYLE has 54 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.17 seconds
cpu time 0.17 seconds
14 + data VTABLE ;
15 + set SASHELP.VTABLE;
16 + crdate =.;
17 + modate =.;
18 + run;
NOTE: There were 1188 observations read from the data set SASHELP.VTABLE.
NOTE: The data set WORK.VTABLE has 1188 observations and 41 variables.
NOTE: DATA statement used (Total process time):
real time 0.31 seconds
cpu time 0.29 seconds
[新增2016-12-15]
回到OP并稍微修改PROC SQL
步骤,我已经制作了一些看起来像我认为你要求的东西:
%macro drop_check2(lib2,dsn,format=YYMMDD10.);
proc sql noprint;
select distinct catx(".",libname,memname), name
into :dsns separated by " ", :varname separated by " "
from dictionary.columns
where libname = upcase("&lib2") and format="&format"
order by 1;
quit;
%if &sqlrc NE 0
%then %do;
%put PROC SQL returned a warning or error. Terminating macro.;
%goto mout;
%end;
%else %do;
%if &sqlobs LE 0
%then %do;
%put PROC SQL did not return any rows. Terminating macro.;
%goto mout;
%end;
%else %do;
%local olddsn curdsn curvbl i;
data &dsn.;
set
%let olddsn=;
%do i=1 %to &sqlobs;
%let curdsn=%scan(&dsns,&i,%str( ));
%let curvbl=%scan(&varname,&i,%str( ));
%if &curdsn NE &olddsn
%then %do;
%if &olddsn NE
%then %do;
)
%end;
%let olddsn=&curdsn.;
&curdsn (keep=&curvbl
%end;
%else %do;
&curvbl
%end;
%end;
);
%do i=1 %to &sqlobs;
%scan(&varname,&i,%str( ))=.;
%end;
run;
%end;
%end;
%mout:
%MEND drop_check2;
options mprint;
%drop_check2(sashelp,er2,format=DATETIME.)
这将产生以下数据步骤:
MPRINT(DROP_CHECK2): data er2;
MPRINT(DROP_CHECK2): set SASHELP.VCATALG (keep=created modified ) SASHELP.VEXTFL (keep=modate )
SASHELP.VSTYLE (keep=crdate ) SASHELP.VTABLE (keep=crdate modate );
MPRINT(DROP_CHECK2): created=.;
MPRINT(DROP_CHECK2): modified=.;
MPRINT(DROP_CHECK2): modate=.;
MPRINT(DROP_CHECK2): crdate=.;
MPRINT(DROP_CHECK2): crdate=.;
MPRINT(DROP_CHECK2): modate=.;
MPRINT(DROP_CHECK2): run;
NOTE: There were 17212 observations read from the data set SASHELP.VCATALG.
NOTE: There were 14 observations read from the data set SASHELP.VEXTFL.
NOTE: There were 54 observations read from the data set SASHELP.VSTYLE.
NOTE: There were 1180 observations read from the data set SASHELP.VTABLE.
NOTE: The data set WORK.ER2 has 18460 observations and 4 variables.
您将看到输出数据集/表仅包含4个变量/列,但每个输入数据集/表中的每个观察值都包含一行。如果在多个输入数据集/表中存在具有相同名称的变量/列,那么这些变量/列将被设置为多次丢失,但这只是效率低下。
更重要的是,如果重复的变量/列在其出现的数据集/表中具有不同的属性,则它将具有第一个数据集/表中的属性。
也无法识别行,因为没有包含标识符或键的变量/列,但这似乎是您要求的。