SAS宏传递SQL或代码以在宏中使用

时间:2017-10-16 07:53:16

标签: macros sas sas-macro proc-sql

我对SAS宏编程比较陌生,我主要使用它来使我的代码“更干净”并避免重复代码中的错误。

我做了一些谷歌搜索,但没有找到简单的方法。

我首先有2个问题 - 如何将列列表传递给宏?

我想在一般代码中看到像这样的宏:

proc sql;
create table &usefulTable as 
%DoStuff('col1, col3, col9', 'col1 = 12 or (col2 between 1 and 3)')
;

基本上我将列值作为第一个参数传递,将where子句作为第二个参数传递。

是否可以将宏作为列名作为第一个参数,并将第二个参数作为where子句的一部分使用?

%MACRO DoStuff(col, cond);
    select
    &col separated by ',' ,
    'source1' as source
  from &someNiceTable
  where &cond
union
    select
    &col separated by ',' ,
    'source2' as source
  from &someNiceOtherTable
  where &cond
%mend;

上面是示例基本宏,显示了我打算做的类似功能,在这种情况下,2个表的并集,同时添加新列,从哪个表定义设置记录。基本上总是会为几个表应用相同的条件,然后它们将与union连接,并添加一个额外的列。

很高兴得到一些jelp。

说实话,我面临的最大问题是传递are变量,因为我可以将列名称用作宏中的硬编码值,但问题是where子句,因为它经常更改。

2 个答案:

答案 0 :(得分:2)

你走在正确的轨道上。引用这些参数参数部分正确,因为第一个参数(列列表)将被解释为3个单独的参数,而另一个(其中条件)将被解释为名为col1的关键字参数。但是,这需要您在宏定义中dequote这些参数。一种更简单的方法是在宏调用中使用%str()

您在separated by中对proc sql的使用情况也很严重。这与into语句一起使用,用于将select语句中的值存储到宏变量中。

您的宏应该如下所示:

%MACRO DoStuff(col, cond);
    select
    &col,
    'source1' as source
  from &someNiceTable
  where &cond
union
    select
    &col,
    'source2' as source
  from &someNiceOtherTable
  where &cond
%mend;

呼叫应该是这样的:

proc sql;
create table &usefulTable as 
%DoStuff(%str(col1, col3, col9), %str(col1 = 12 or (col2 between 1 and 3)))
;
quit;

答案 1 :(得分:2)

如果您将值作为带引号的字符串传递,并希望在没有引号的情况下使用它们,则可以使用<div></div>宏函数调用DEQUOTE()函数。

%SYSFUNC()

请注意,这也将处理删除您可能使用的任何宏引用而不是文字引号字符以保护您的嵌入式逗号。

请注意,对于您的COND变量,您可以在条件周围添加%MACRO DoStuff(col, cond); select %sysfunc(dequote(&col)) , 'source1' as source from &someNiceTable where %sysfunc(dequote(&cond)) ; %mend; 而不是引号或宏引号,以防止宏调用混淆。

所以你的电话看起来就像其中一个:

()

我发现通过它们之间的空格而不是逗号来传递变量列表要好得多。这样它们就可以直接用于普通的SAS语句中。只有SQL才能使用逗号作为分隔符。因此,请让宏代码添加逗号,以便宏的用户不必担心添加它们。

%DoStuff(col='col1, col3, col9',cond=(col1 = 12 or (col2 between 1 and 3)))
%DoStuff(col=%str(col1, col3, col9),cond=(col1 = 12 or (col2 between 1 and 3)))

您还可以使用其他字符(例如%macro mymac(dsn,varlist); %local sqllist; %let sqllist=%sysfunc(translate(%sysfunc(compbl(&varlist)),%str(,),%str( ))); proc print data=&dsn ; var &varlist ; run; proc sql ; select &sqllist from &dsn ; quit; %mend mymac ; |)作为值列表中的分隔符。

^