Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获取SAS存储进程中按动态列列表筛选的数据_Sas_Sas Macro - Fatal编程技术网

获取SAS存储进程中按动态列列表筛选的数据

获取SAS存储进程中按动态列列表筛选的数据,sas,sas-macro,Sas,Sas Macro,我的目标是创建一个SAS存储进程,即返回单个数据集的数据,并根据传入存储进程的多值输入参数筛选该数据集中的列 有没有一种简单的方法可以做到这一点? 有没有办法做到这一点? 这是我到目前为止所拥有的。我使用宏动态生成KEEP语句来定义要返回的列。我在顶部定义了宏变量,以模拟通过SAS BI Web服务调用时传递到存储进程中的内容,因此不幸的是,这些变量必须保持原样。这就是我尝试使用VVALUEX方法将列名字符串转换为变量名的原因 注意-我是SAS的新手 libname fetchlib meta

我的目标是创建一个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服务运行它时,它也不会按任何列进行过滤。

好的,我想我对您在这里所做的有些了解

您可以结合使用KEEP和RENAME来恢复变量名

KEEP
        %do k=1 %to (&INCCOL_COUNT);
             var&k
        %end;
        ;
这有一个等价物

RENAME
        %do k=1 %to (&INCCOL_COUNT);
             var&k = &&inccol&k.
        %end;
        ;
现在,只要用户不单独保留原始变量,就可以了。(如果他们这样做,那么您将得到一个冲突和一个错误)

如果这种方式对你的需求不起作用,而且我没有一个解决方案,因为我没有服务器玩,你可以考虑用稍微不同的方式来尝试。

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的内容,您实际上可能有一种更简单的方法来实现这一点

导出
行中,您有各种格式选项。因此,假设我们有一个数据集,它只是原始数据集的一个子集:

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;

然后写下来。我只是猜测您可以在此上下文中使用视图。

事实证明,实现这一点的最简单方法是更改将列(又称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栏


我认为VVALUE(&&inccol&k)是正确的,而不是VVALUEX,如果我理解正确的话(我不通过元数据服务器工作,所以我不确定)。我还建议将引号保留在宏变量之外是正确的(尽管两者都是合法的);也就是说,%let inccol1=街道;然后是v值(&&inccolk.)。是&inccol1等,这正是BI给你的,还是不是宏变量的文本变量?如果是前者,那么我的答案就行了。如果不是,那么这就有点复杂了。不管BI web服务如何,存储进程都允许包含多个值的参数。他们很难合作。当传递3个值时,名为x的参数将生成变量x、x0、x1、x2和x3。x0保存计数(3),x等于x1。x1、x2和x3是三个参数。奇怪,但据我所知,这就是它的工作原理。整个帖子都是推测性的,因为我没有任何方法来测试这些。我很感谢你的回复。这些建议很有帮助,我从中学到了一些,但不幸的是并没有解决我的问题。导致这一点非常困难的原因是变量名列表实际上只是字符串,SAS似乎不喜欢将字符串用作变量名。这就是为什么我使用VVALUEX来获取变量名。然而,VVALUEX在宏KEEP或RENAME语句中似乎不起作用。因此,如果变量名并非都是字符串,那么您的答案可能会起作用。字符串是什么意思?他们周围有引号吗?我将努力找出如何将“字符串”转换为“文本”,这应该很好。VVALUEX在任何情况下都不会返回列名,所以我不理解在那种上下文中使用它——它返回列值。我想我做了一些不好的假设。我所说的字符串是指在其周围有引号的东西。我的假设是这是一个字符串:%let inccol='street';这是一个变量名:%let inccol=street;第二个更容易使用,但我一直假设第一个是通过BI Web服务传递到存储进程中的引用。我一定要弄清楚,这是个好问题。文本是SAS可能解释为SAS代码的任何内容-如果可以将其用作宏变量,则该宏变量中的内容定义为文本(即所有宏变量都是文本)。所以,至少,如果你有
%,那就让blah='stuff'
您可以通过编程删除引号,然后让
%let blah=stuff这将是可用的。您还可以将一个变量称为
'variablename'n
(一个命名文字),它可能很笨拙,但可能是可行的。