SAS MACRO-在宏中concrenate SQL字符串



我有一个libY.tableX,每个记录都有一些SQL字符串,如下面的字符串和其他字段,用于写入执行结果。

select count(*) from libZ.tableK
select sum(fieldV) from libZ.tableK
select min(dsitact) from libZ.tableK

这是我的步骤:

  1. 系统会提示用户选择一个库和表,并将值传递给vars&sel_livraria和&sel_tabela
  2. 我的第一个块是proc-sql,用于从该记录中获取所有sql字符串
  3. 我的第二个块正在尝试concrenate所有的字符串,以便进一步使用结果更新我的表。macro-isBlank是张和金在他们的sas论文中推荐的
  4. 我的第3个块是执行concrenated sql字符串,并用结果更新表
%macro exec_strings;
proc sql noprint ;
select livraria, tabela, sql_tot_linhas, sql_sum_num, sql_min_data, sql_max_data
into :livraria, :tabela, :sql_tot_linhas, :sql_sum_num, :sql_min_data, :sql_max_data
from libY.tableX    
where livraria='&sel_livraria'
and tabela='&sel_tabela';
quit;
%LET mystring1 =%str(tot_linhas=(&sql_tot_linhas));
%LET separador =%str(,);
%if %isBlank(&sql_sum_num) %then %LET mystring2=&mystring1;
%else %LET mystring2= %sysfunc(catx(&separador,&mystring1,%str(sum_num=(&sql_tot_linhas))));
%if %isBlank(&sql_min_data) %then %LET mystring3=&mystring2 ;
%else %LET mystring3= %sysfunc(catx(&separador,&mystring2,%str(min_data=(&sql_min_data))));
%if %isBlank(&sql_max_data) %then %LET mystring0=&mystring3;
%else %LET mystring0= %sysfunc(catx(&separador,&mystring3,%str(max_data=(&sql_min_data))));
%PUT &mystring0;
proc sql noprint;
update libY.tableX
set &mystring0
where livraria='&sel_livraria'
and tabela='&sel_tabela';
quit;
%mend;

我对上面代码的问题是,我在最后一个concrenated字符串中得到了这个错误,&mystring 0.

tot_linhas=(&sql_tot_linhas),sum_num=(&sql_tot_linhas),min_data=(&sql_min_data),max_data=(&sql_min_data)
_                         _                          _                        _                                            
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant,  a missing value, BTRIM, INPUT, PUT, SUBSTRING, USER. 

感谢的任何帮助

从您的描述中很难判断您要做什么,但在您共享的代码片段中存在一些明显的编码问题。

首先,宏表达式不是在以单引号为界的字符串文字中计算的。必须使用双引号。

where livraria="&sel_livraria"

第二,你不想使用任何CAT。。。((宏代码中的SAS功能。主要是因为你不需要它们。如果要连接宏代码中的值,只需将它们并排键入即可。但也因为它们不能很好地与%SYSFUNC((配合使用,因为它们允许它们的参数是数字或字符,所以%SYSFUNC.((必须根据您传递的字符串来猜测它是否应该告诉SAS函数这些字符串是数字值或字符值。

所以也许是这样的:

%let mystring=tot_linhas=(&sql_tot_linhas);
%if not %isBlank(&sql_sum_num) %then 
%LET mystring=&mystring,sum_num=(&sql_tot_linhas)
;
%if not %isBlank(&sql_min_data) %then 
%LET mystring=&mystring,min_data=(&sql_min_data)
;
%if not %isBlank(&sql_max_data) %then
%LET mystring=&mystring,max_data=(&sql_max_data)
;

请注意,在修改该代码时,我还清理了一些明显的错误。就像额外的&在传递给%ISBLANK((宏的值和将最小值分配给最大变量的过程中。

但是,在数据步骤中生成字符串可能会更容易,在该步骤中,您可以测试实际变量的值,如果需要,还可以实际使用CATX((函数。

好的,所以我遵循Tom的评论,并以一个有效的proc-sql解决方案结束!

proc sql;
select sql_tot_linhas,
(case when sql_sum_num = '' then "0" else sql_sum_num end),
(case when sql_min_data = '' then "." else sql_min_data end),
(case when sql_max_data = '' then "." else sql_max_data end)
into:sql_linhas, :sql_numeros, :sql_mindata, :sql_mxdata
from libY.tableX 
where livraria="&sel_livraria"
and tabela="&sel_tabela";
quit;
proc sql;
update libY.tableX 
set tot_linhas = (&sql_linhas),
sum_num =(&sql_numeros),
min_data = (&sql_mindata),
max_data = (&sql_mxdata)           
where livraria="&sel_livraria"
and tabela="&sel_tabela";
quit;

汤姆:(

最新更新