Production Ready Macros for SAS Application Developers
https://github.com/sasjs/core
mm_webout.sas
Go to the documentation of this file.
1 /**
2  @file mm_webout.sas
3  @brief Send data to/from SAS Stored Processes
4  @details This macro should be added to the start of each Stored Process,
5  **immediately** followed by a call to:
6 
7  %mm_webout(FETCH)
8 
9  This will read all the input data and create same-named SAS datasets in the
10  WORK library. You can then insert your code, and send data back using the
11  following syntax:
12 
13  data some datasets; * make some data ;
14  retain some columns;
15  run;
16 
17  %mm_webout(OPEN)
18  %mm_webout(ARR,some) * Array format, fast, suitable for large tables ;
19  %mm_webout(OBJ,datasets) * Object format, easier to work with ;
20 
21  Finally, wrap everything up send some helpful system variables too
22 
23  %mm_webout(CLOSE)
24 
25 
26  @param action Either FETCH, OPEN, ARR, OBJ or CLOSE
27  @param ds The dataset to send back to the frontend
28  @param dslabel= value to use instead of the real name for sending to JSON
29  @param fmt= set to N to send back unformatted values
30 
31  @version 9.3
32  @author Allan Bowe
33 
34 **/
35 %macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y);
36 %global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
37  sasjs_tables;
38 %local i tempds;
39 
40 %if &action=FETCH %then %do;
41  %if %str(&_debug) ge 131 %then %do;
42  options mprint notes mprintnest;
43  %end;
44  %let _webin_file_count=%eval(&_webin_file_count+0);
45  /* now read in the data */
46  %do i=1 %to &_webin_file_count;
47  %if &_webin_file_count=1 %then %do;
48  %let _webin_fileref1=&_webin_fileref;
49  %let _webin_name1=&_webin_name;
50  %end;
51  data _null_;
52  infile &&_webin_fileref&i termstr=crlf;
53  input;
54  call symputx('input_statement',_infile_);
55  putlog "&&_webin_name&i input statement: " _infile_;
56  stop;
57  data &&_webin_name&i;
58  infile &&_webin_fileref&i firstobs=2 dsd termstr=crlf encoding='utf-8';
59  input &input_statement;
60  %if %str(&_debug) ge 131 %then %do;
61  if _n_<20 then putlog _infile_;
62  %end;
63  run;
64  %let sasjs_tables=&sasjs_tables &&_webin_name&i;
65  %end;
66 %end;
67 
68 %else %if &action=OPEN %then %do;
69  /* fix encoding */
70  OPTIONS NOBOMFILE;
71  data _null_;
72  rc = stpsrv_header('Content-type',"text/html; encoding=utf-8");
73  run;
74 
75  /* setup json */
76  data _null_;file &fref encoding='utf-8';
77  %if %str(&_debug) ge 131 %then %do;
78  put '>>weboutBEGIN<<';
79  %end;
80  put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"';
81  run;
82 
83 %end;
84 
85 %else %if &action=ARR or &action=OBJ %then %do;
86  %if &sysver=9.4 %then %do;
87  %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt
88  ,engine=PROCJSON,dbg=%str(&_debug)
89  )
90  %end;
91  %else %do;
92  %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt
93  ,engine=DATASTEP,dbg=%str(&_debug)
94  )
95  %end;
96 %end;
97 %else %if &action=CLOSE %then %do;
98  %if %str(&_debug) ge 131 %then %do;
99  /* if debug mode, send back first 10 records of each work table also */
100  options obs=10;
101  data;run;%let tempds=%scan(&syslast,2,.);
102  ods output Members=&tempds;
103  proc datasets library=WORK memtype=data;
104  %local wtcnt;%let wtcnt=0;
105  data _null_;
106  set &tempds;
107  if not (name =:"DATA");
108  i+1;
109  call symputx('wt'!!left(i),name,'l');
110  call symputx('wtcnt',i,'l');
111  data _null_; file &fref encoding='utf-8';
112  put ",""WORK"":{";
113  %do i=1 %to &wtcnt;
114  %let wt=&&wt&i;
115  proc contents noprint data=&wt
116  out=_data_ (keep=name type length format:);
117  run;%let tempds=%scan(&syslast,2,.);
118  data _null_; file &fref encoding='utf-8';
119  dsid=open("WORK.&wt",'is');
120  nlobs=attrn(dsid,'NLOBS');
121  nvars=attrn(dsid,'NVARS');
122  rc=close(dsid);
123  if &i>1 then put ','@;
124  put " ""&wt"" : {";
125  put '"nlobs":' nlobs;
126  put ',"nvars":' nvars;
127  %mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=DATASTEP)
128  %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=DATASTEP)
129  data _null_; file &fref encoding='utf-8';
130  put "}";
131  %end;
132  data _null_; file &fref encoding='utf-8';
133  put "}";
134  run;
135  %end;
136  /* close off json */
137  data _null_;file &fref mod encoding='utf-8';
138  _PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
139  put ",""SYSUSERID"" : ""&sysuserid"" ";
140  put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
141  put ",""_DEBUG"" : ""&_debug"" ";
142  _METAUSER=quote(trim(symget('_METAUSER')));
143  put ",""_METAUSER"": " _METAUSER;
144  _METAPERSON=quote(trim(symget('_METAPERSON')));
145  put ',"_METAPERSON": ' _METAPERSON;
146  put ',"_PROGRAM" : ' _PROGRAM ;
147  put ",""SYSCC"" : ""&syscc"" ";
148  put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
149  put ",""SYSHOSTNAME"" : ""&syshostname"" ";
150  put ",""SYSJOBID"" : ""&sysjobid"" ";
151  put ",""SYSSITE"" : ""&syssite"" ";
152  put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
153  put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
154  put "}" @;
155  %if %str(&_debug) ge 131 %then %do;
156  put '>>weboutEND<<';
157  %end;
158  run;
159 %end;
160 
161 %mend;