在 proc sql 中解析为语句的 SAS 宏
SAS macro to resolve in proc sql into statement
谁能帮我解决这里的语法错误。
Y 是包含一些值的数据集,比如 1,2,3,4(实际上它包含很多记录)
/*This is working fine*/
proc sql;
select count(*) into:m from y;
select x into:a1 - :a4 from y;
quit;
%put &m &a1 &a2 &a3 &a4;
/*When i am trying to create a macro which will have a1 to a4 values, it's giving me error. below is my approach*/
proc sql;
select count(*) into:m from y;
select x into:a1 - :a||trim(left(&m.)) from y;
quit;
%put &m &a1 &a2 &a3 &a4;
请有人帮我解决这个问题,解释一下错误的原因。
你不需要再告诉有多少了。 SQL 将创建足够的变量。
data y;
do x = 1 to 4;
output;
end;
run;
proc sql;
select count(*) into:m from y;
select x into:a1- from y;
quit;
%put &m &a1 &a2 &a3 &a4;
这至少从 9.3 开始有效。
虽然 DN 在另一个答案中是正确的,您真的不必再为此烦恼了,但我认为向您展示您尝试中的错误很有用 - 这并不是一种不合理的方法。
您不能像以前那样使用 trim
。这将对字符表达式进行操作,而不是对程序代码进行操作 - 宏变量正在生成(程序代码)。您有几个选项可以执行此操作。
首先是%trim
autocall macro。这就是您直接做您想做的事情的方式。
proc sql;
select count(*) into :ccount trimmed from sashelp.class;
select name into :a1 - :a%trim(&ccount.) from sashelp.class;
quit;
%put &ccount &a1 &a2 &a3 &a4;
其次,SQL 实际上会以两种可能的方式为您执行此操作。
trimmed
关键词
separated by
trimmed
关键字作为 into 子句的一部分,或者使用 separated by
即使只有一个结果值,也会导致修剪结果(因此,左对齐,后面没有空格或preceding) 存储在目标宏变量中。 (为什么 separated by
的默认值与 not 的默认值不同是 SAS 中与不破坏有效代码相关的奇怪事情之一,即使它是一个愚蠢的结果。)
proc sql;
select count(*) into :ccount trimmed from sashelp.class;
select name into :a1 - :a&ccount. from sashelp.class;
quit;
%put &ccount &a1 &a2 &a3 &a4;
语法错误可能是由于不了解宏处理器的工作原理造成的。它只是一个生成文本的工具。生成的文本需要是有效的 SAS 代码才能执行。所以试着写这样的东西:
into :a1 - :a||trim(left(&m.))
将不起作用。唯一的宏触发器是对 M 宏变量的引用。所以这将评估为:
into :a1 - :a||trim(left( 4))
但是 INTO 运算符只需要那里的宏变量名称列表的上限名称。它无法处理 ||连接运算符或调用函数,如 TRIM() 或 LEFT().
幸运的是,您不需要这些,因为 PROC SQL 的 INTO 子句足够智能,可以只生成您需要的宏变量。如果您使用的是当前版本的 SAS,您可以将上限留空。
into :a1 -
或者,如果您 运行 使用旧版本,您只需使用大于任何预期观察次数的上限。
into :a1-:a999999
此外,您不需要 运行 查询两次以找出找到的记录数 SQL。它会将计数设置到自动宏变量 SQLOBS 中。所以你的查询变成:
proc sql noprint;
select x into :a1- from y;
%let m=&sqlobs;
quit;
谁能帮我解决这里的语法错误。 Y 是包含一些值的数据集,比如 1,2,3,4(实际上它包含很多记录)
/*This is working fine*/
proc sql;
select count(*) into:m from y;
select x into:a1 - :a4 from y;
quit;
%put &m &a1 &a2 &a3 &a4;
/*When i am trying to create a macro which will have a1 to a4 values, it's giving me error. below is my approach*/
proc sql;
select count(*) into:m from y;
select x into:a1 - :a||trim(left(&m.)) from y;
quit;
%put &m &a1 &a2 &a3 &a4;
请有人帮我解决这个问题,解释一下错误的原因。
你不需要再告诉有多少了。 SQL 将创建足够的变量。
data y;
do x = 1 to 4;
output;
end;
run;
proc sql;
select count(*) into:m from y;
select x into:a1- from y;
quit;
%put &m &a1 &a2 &a3 &a4;
这至少从 9.3 开始有效。
虽然 DN 在另一个答案中是正确的,您真的不必再为此烦恼了,但我认为向您展示您尝试中的错误很有用 - 这并不是一种不合理的方法。
您不能像以前那样使用 trim
。这将对字符表达式进行操作,而不是对程序代码进行操作 - 宏变量正在生成(程序代码)。您有几个选项可以执行此操作。
首先是%trim
autocall macro。这就是您直接做您想做的事情的方式。
proc sql;
select count(*) into :ccount trimmed from sashelp.class;
select name into :a1 - :a%trim(&ccount.) from sashelp.class;
quit;
%put &ccount &a1 &a2 &a3 &a4;
其次,SQL 实际上会以两种可能的方式为您执行此操作。
trimmed
关键词separated by
trimmed
关键字作为 into 子句的一部分,或者使用 separated by
即使只有一个结果值,也会导致修剪结果(因此,左对齐,后面没有空格或preceding) 存储在目标宏变量中。 (为什么 separated by
的默认值与 not 的默认值不同是 SAS 中与不破坏有效代码相关的奇怪事情之一,即使它是一个愚蠢的结果。)
proc sql;
select count(*) into :ccount trimmed from sashelp.class;
select name into :a1 - :a&ccount. from sashelp.class;
quit;
%put &ccount &a1 &a2 &a3 &a4;
语法错误可能是由于不了解宏处理器的工作原理造成的。它只是一个生成文本的工具。生成的文本需要是有效的 SAS 代码才能执行。所以试着写这样的东西:
into :a1 - :a||trim(left(&m.))
将不起作用。唯一的宏触发器是对 M 宏变量的引用。所以这将评估为:
into :a1 - :a||trim(left( 4))
但是 INTO 运算符只需要那里的宏变量名称列表的上限名称。它无法处理 ||连接运算符或调用函数,如 TRIM() 或 LEFT().
幸运的是,您不需要这些,因为 PROC SQL 的 INTO 子句足够智能,可以只生成您需要的宏变量。如果您使用的是当前版本的 SAS,您可以将上限留空。
into :a1 -
或者,如果您 运行 使用旧版本,您只需使用大于任何预期观察次数的上限。
into :a1-:a999999
此外,您不需要 运行 查询两次以找出找到的记录数 SQL。它会将计数设置到自动宏变量 SQLOBS 中。所以你的查询变成:
proc sql noprint;
select x into :a1- from y;
%let m=&sqlobs;
quit;