2014-03-25 96 views
0

我的目标是创建一个SAS存储过程,用于返回单个数据集的数据并根据传入的多值输入参数过滤该数据集中的列存储过程。获取SAS存储过程中通过动态列表过滤的数据

有没有简单的方法来做到这一点?

有没有办法做到这一点?

这是我到目前为止。我正在使用宏来动态生成KEEP语句来定义要返回的列。我在顶部定义了宏变量,以模拟通过SAS BI Web服务调用时传递到存储过程的内容,因此不幸的是,这些变量必须保持原样。这就是为什么我试图使用VVALUEX方法将列名称字符串转换为变量名称。

注意 - 我是新来的SAS

libname fetchlib meta library="lib01" metaserver="123.12.123.123" 
password="password" port=1234 
repname="myRepo" user="myUserName"; 

/* This data represents input parameters to stored process and 
* is removed in the actual stored process*/ 
%let inccol0=3; 
%let inccol='STREET'; 
%let inccol1='STREET'; 
%let inccol2='ADDRESS'; 
%let inccol3='POSTAL'; 
%let inccol_count=3; 

%macro keepInputColumns; 
    %if &INCCOL_COUNT = 1 %then 
     &inccol; 
    %else 
     %do k=1 %to (&INCCOL_COUNT); 
      var&k = VVALUEX(&&inccol&k); 
     %end; 
     KEEP 
     %do k=1 %to (&INCCOL_COUNT); 
      var&k 
     %end; 
     ; 
%mend; 

data test1; 
    SET fetchlib.Table1; 
    %keepInputColumns; 
run; 

/*I switch this output to _WEBOUT in the actual stored process*/ 
proc json out='C:\Logs\Log1.txt'; 
    options firstobs=1 obs=10; 
    export test1 /nosastags; 
run; 

有一些问题与此有关。输出使用var1,var2和var3作为列名,而不是实际的列名。当我将输出更改为_webout并使用BI Web Services运行时,它也不会被任何列过滤。

+0

我觉得VVALUE(&& inccol&K)是正确的,而不是VVALUEX,如果我理解你在做什么正确(我不通过元数据服务器工作,所以我不确定)。我也建议保留引用的宏观变量被认为是正确的(尽管两者都是合法的);即%让inccol1 = STREET;然后vvalue(“&& inccolk。”)。 – Joe

+0

是否是&inccol1等究竟是什么BI给你,或者它是一个文本变量是不是一个宏变量?如果前者那么我的答案会起作用。如果不是,那么这有点复杂。 – Joe

+0

无论BI Web服务如何,存储过程都允许保存多个值的参数。他们很难合作。当传递3个值时,名为x的参数将生成变量x,x0,x1,x2和x3。 x0保存计数(3),并且x等于x1。 x1,x2和x3是三个参数。奇怪,但就我所知,这就是它的工作原理。 – Scampbell

回答

0

事实证明,最简单的实现方法是改变列(又名SAS变量)传递到存储过程的方式。尽管Joe的回答很有帮助,但我最终通过将列作为空格分隔列列传递给keep语句来解决问题,这大大简化了SAS代码,因为我不必处理动态列列表。

libname fetchlib meta library="lib01" metaserver="123.12.123.123" 
password="password" port=1234 
repname="myRepo" user="myUserName";"&repository" user="&user"; 

proc json out=_webout; 
    export fetchlib.&tablename(keep=&columns) /nosastags; 
run; 

&columns被设置为这样的事情:

列1列2栏3

1

好的,我想我对你在这里做的事有一些了解。

您可以联合使用KEEP和RENAME来获取您的变量名称。

KEEP 
     %do k=1 %to (&INCCOL_COUNT); 
      var&k 
     %end; 
     ; 

这具有等效

RENAME 
     %do k=1 %to (&INCCOL_COUNT); 
      var&k = &&inccol&k. 
     %end; 
     ; 

而现在,只要用户不单独保留原有的变量,你没事。 (如果他们这样做,那么你会得到一个冲突和一个错误)。

如果这种方式无法满足您的需求,并且我没有针对_webout的解决方案,因为我没有服务器来玩,您可以考虑以稍微不同的方式尝试。

proc format; 
    value agef 
    11-13 = '11-13' 
    14-16 = '14-16'; 
quit; 

ods output report=mydata(drop=_BREAK_); 
proc report data=sashelp.class nowd; 
format age agef.; 
columns name age; 
run; 
ods output close; 

第一部分只是一个proc格式,表明这种格式化值不是基础值。 (我认为这是理想的,好像它不是这很容易。)

现在,您可以更方便地将数据集中的数据更方便一些,不过您可以将其放到JSON中。在你的例子中,你会做类似

ods output report=work.mydata(drop=_BREAK_); 
proc report data=fetchlib.Table1 nowd; 
columns 

    %do k=1 %to (&INCCOL_COUNT); 
     &&inccol&k.; 
    %end; 
; 
run; 
ods output close; 

然后你可以发送该数据集到JSON或其他。实际上你甚至可能比这更直接,但我几乎不知道PROC JSON的任何内容。

阅读有关JSON的更多信息,您可能实际上有更简单的方法来完成此操作。

export行中,您有各种格式选项。因此,假设我们有一个数据集就是原来的一个子集:

proc json out='C:\Logs\Log1.txt'; 
    options firstobs=1 obs=10; 
    export fetchlib.Table1 
    (
    %do k=1 %to (&INCCOL_COUNT); 
       &&inccol&k.; 
      %end; 
    ) 

/nosastags FMTCHARACTER FMTDATETIME FMTNUMERIC ; 
run; 

此方法不会允许变量为了改变;如果需要的话,可以使用中间数据集:

data intermediate/view=intermediate; 
set fetchlib.Table1; 
retain 
     %do k=1 %to (&INCCOL_COUNT); 
      &&inccol&k.; 
     %end; 
; 
keep 
     %do k=1 %to (&INCCOL_COUNT); 
      &&inccol&k.; 
     %end; 
; 
run; 

然后写出来。我只是猜测你可以在这种情况下使用视图。

+0

这整个帖子都是推测性的,因为我没有任何测试任何方法。 – Joe

+0

我很欣赏这种回应。这些是我从中学到的有用建议,但不幸的是没有解决我的问题。导致这种情况非常困难的一个原因是,变量名称列表实际上只是字符串,当您尝试将字符串用作变量名称时,SAS似乎并不喜欢它。这就是我使用VVALUEX获取变量名称的原因。但是,VVALUEX似乎不适用于宏KEEP或RENAME语句。因此,如果变量名不是所有的字符串,那么你的答案可能会起作用。 – Scampbell

+1

你是什么意思的字符串?他们有围绕他们的报价吗?我会努力找出如何将“字符串”转换为“文本”,这应该工作得很好。 VVALUEX在任何情况下都不返回列名,所以我不明白在那种情况下使用它 - 它返回列_values_。 – Joe