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