mirror of
https://github.com/sasjs/core.git
synced 2026-01-06 17:10:05 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b75369b28d | ||
|
|
63871db170 | ||
|
|
6456c2f6e2 | ||
|
|
36faa194a8 | ||
|
|
093dc87aad | ||
|
|
ca045e3ebf | ||
|
|
be5e2f371d | ||
|
|
6d15465bac | ||
|
|
2031a5b0c0 | ||
|
|
62837b512b | ||
|
|
5d5a99fd77 | ||
|
|
1b5effd584 | ||
|
|
1613ab2c9e | ||
|
|
a2df4e35be | ||
|
|
aabbcfdf6b | ||
|
|
7b7759e1ce | ||
|
|
e5a3053600 |
2
.github/workflows/run-tests.yml
vendored
2
.github/workflows/run-tests.yml
vendored
@@ -78,7 +78,5 @@ jobs:
|
|||||||
SECRET: ${{secrets.SECRET}}
|
SECRET: ${{secrets.SECRET}}
|
||||||
SAS_USERNAME: ${{secrets.SAS_USERNAME}}
|
SAS_USERNAME: ${{secrets.SAS_USERNAME}}
|
||||||
SAS_PASSWORD: ${{secrets.SAS_PASSWORD}}
|
SAS_PASSWORD: ${{secrets.SAS_PASSWORD}}
|
||||||
SERVER_URL: ${{secrets.SERVER_URL}}
|
|
||||||
SERVER_TYPE: ${{secrets.SERVER_TYPE}}
|
|
||||||
ACCESS_TOKEN: ${{secrets.ACCESS_TOKEN}}
|
ACCESS_TOKEN: ${{secrets.ACCESS_TOKEN}}
|
||||||
REFRESH_TOKEN: ${{secrets.REFRESH_TOKEN}}
|
REFRESH_TOKEN: ${{secrets.REFRESH_TOKEN}}
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -36,21 +36,21 @@ Documentation: https://core.sasjs.io
|
|||||||
- OS independent
|
- OS independent
|
||||||
- Works on all SAS Platforms
|
- Works on all SAS Platforms
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _mf_, _mp_
|
- Prefixes: `mf_`, `mp_`
|
||||||
|
|
||||||
### DDL folder (All Platforms)
|
### DDL folder (All Platforms)
|
||||||
|
|
||||||
- OS independent
|
- OS independent
|
||||||
- Works on all SAS Platforms
|
- Works on all SAS Platforms
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _mddl_(lib)_ -> where lib can be "SAS" (in relation to a SAS component) or "DC" (in relation to a Data Controller component)
|
- Prefixes: `mddl_(lib)_` -> where lib can be "SAS" (in relation to a SAS component) or "DC" (in relation to a Data Controller component)
|
||||||
|
|
||||||
This library will not be used for storing data entries (such as formats or datalines). Where this becomes necessary in the future, a new repo will be created, in order to keep the NPM bundle size down (for the benefit of those looking to embed purely macros in their applications).
|
This library will not be used for storing data entries (such as formats or datalines). Where this becomes necessary in the future, a new repo will be created, in order to keep the NPM bundle size down (for the benefit of those looking to embed purely macros in their applications).
|
||||||
|
|
||||||
### FCMP folder (All Platforms)
|
### FCMP folder (All Platforms)
|
||||||
|
|
||||||
- Function and macro names are identical, except for special cases
|
- Function and macro names are identical, except for special cases
|
||||||
- Prefixes: _mcf_
|
- Prefixes: `mcf_`
|
||||||
|
|
||||||
The fcmp macros are used to generate fcmp functions, and can be used with or without the `proc fcmp` wrapper.
|
The fcmp macros are used to generate fcmp functions, and can be used with or without the `proc fcmp` wrapper.
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ endsubmit;
|
|||||||
run;
|
run;
|
||||||
```
|
```
|
||||||
|
|
||||||
- Prefixes: _ml_
|
- Prefixes: `ml_`
|
||||||
|
|
||||||
### META folder (SAS9 only)
|
### META folder (SAS9 only)
|
||||||
|
|
||||||
@@ -81,14 +81,14 @@ Macros used in SAS EBI, which connect to the metadata server.
|
|||||||
- OS independent
|
- OS independent
|
||||||
- Metadata aware
|
- Metadata aware
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _mm_
|
- Prefixes: `mm_`
|
||||||
|
|
||||||
### METAX folder (SAS9 only)
|
### METAX folder (SAS9 only)
|
||||||
|
|
||||||
- OS specific
|
- OS specific
|
||||||
- Metadata aware
|
- Metadata aware
|
||||||
- X command enabled
|
- X command enabled
|
||||||
- Prefixes: _mmw_,_mmu_,_mmx_
|
- Prefixes: `mmx_`
|
||||||
|
|
||||||
### SERVER folder (@sasjs/server only)
|
### SERVER folder (@sasjs/server only)
|
||||||
These macros are used for building applications using [@sasjs/server](https://server.sasjs.io) - an open source REST API for Desktop SAS.
|
These macros are used for building applications using [@sasjs/server](https://server.sasjs.io) - an open source REST API for Desktop SAS.
|
||||||
@@ -96,7 +96,7 @@ These macros are used for building applications using [@sasjs/server](https://se
|
|||||||
- OS independent
|
- OS independent
|
||||||
- @sasjs/server aware
|
- @sasjs/server aware
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _ms_
|
- Prefixes: `ms_`
|
||||||
|
|
||||||
### VIYA folder (Viya only)
|
### VIYA folder (Viya only)
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ Macros used for interfacing with SAS Viya.
|
|||||||
|
|
||||||
- OS independent
|
- OS independent
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _mv_, _mvf_
|
- Prefixes: `mv_`, `mvf_`
|
||||||
|
|
||||||
### XPLATFORM folder (Viya, Meta, and Server)
|
### XPLATFORM folder (Viya, Meta, and Server)
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ Sometimes it is helpful to use a macro that can be used interchangeably regardle
|
|||||||
|
|
||||||
- OS independent
|
- OS independent
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _mx_
|
- Prefixes: `mx_`
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
332
all.sas
332
all.sas
@@ -5826,6 +5826,116 @@ options varlenchk=&optval;
|
|||||||
%put &sysmacroname: &outds is %mf_getfilesize(libds=&outds,format=yes);
|
%put &sysmacroname: &outds is %mf_getfilesize(libds=&outds,format=yes);
|
||||||
|
|
||||||
%mend mp_ds2squeeze;/**
|
%mend mp_ds2squeeze;/**
|
||||||
|
@file
|
||||||
|
@brief Export dataset metadata to a single output table
|
||||||
|
@details Exports the dataset attributes and enginehost information, then
|
||||||
|
converts the datasets into a single output table in the following format:
|
||||||
|
|
||||||
|
|ODS_TABLE:$10.|NAME:$100.|VALUE:$1000.|
|
||||||
|
|---|---|---|
|
||||||
|
|`ATTRIBUTES `|`Data Set Name `|`SASHELP.CLASS `|
|
||||||
|
|`ATTRIBUTES `|`Observations `|`19 `|
|
||||||
|
|`ATTRIBUTES `|`Member Type `|`DATA `|
|
||||||
|
|`ATTRIBUTES `|`Variables `|`5 `|
|
||||||
|
|`ATTRIBUTES `|`Engine `|`V9 `|
|
||||||
|
|`ATTRIBUTES `|`Indexes `|`0 `|
|
||||||
|
|`ATTRIBUTES `|`Created `|`06/08/2020 00:59:14 `|
|
||||||
|
|`ATTRIBUTES `|`Observation Length `|`40 `|
|
||||||
|
|`ATTRIBUTES `|`Last Modified `|`06/08/2020 00:59:14 `|
|
||||||
|
|`ATTRIBUTES `|`Deleted Observations `|`0 `|
|
||||||
|
|`ATTRIBUTES `|`Protection `|`. `|
|
||||||
|
|`ATTRIBUTES `|`Compressed `|`NO `|
|
||||||
|
|`ATTRIBUTES `|`Data Set Type `|`. `|
|
||||||
|
|`ATTRIBUTES `|`Sorted `|`NO `|
|
||||||
|
|`ATTRIBUTES `|`Label `|`Student Data `|
|
||||||
|
|`ATTRIBUTES `|`Data Representation `|`SOLARIS_X86_64, LINUX_X86_64, ALPHA_TRU64, LINUX_IA64 `|
|
||||||
|
|`ATTRIBUTES `|`Encoding `|`us-ascii ASCII (ANSI) `|
|
||||||
|
|`ENGINEHOST `|`Data Set Page Size `|`65536 `|
|
||||||
|
|`ENGINEHOST `|`Number of Data Set Pages `|`1 `|
|
||||||
|
|`ENGINEHOST `|`First Data Page `|`1 `|
|
||||||
|
|`ENGINEHOST `|`Max Obs per Page `|`1632 `|
|
||||||
|
|`ENGINEHOST `|`Obs in First Data Page `|`19 `|
|
||||||
|
|`ENGINEHOST `|`Number of Data Set Repairs `|`0 `|
|
||||||
|
|`ENGINEHOST `|`Filename `|`/opt/sas/sas9/SASHome/SASFoundation/9.4/sashelp/class.sas7bdat `|
|
||||||
|
|`ENGINEHOST `|`Release Created `|`9.0401M7 `|
|
||||||
|
|`ENGINEHOST `|`Host Created `|`Linux `|
|
||||||
|
|`ENGINEHOST `|`Inode Number `|`28314616 `|
|
||||||
|
|`ENGINEHOST `|`Access Permission `|`rw-r--r-- `|
|
||||||
|
|`ENGINEHOST `|`Owner Name `|`sas `|
|
||||||
|
|`ENGINEHOST `|`File Size `|`128KB `|
|
||||||
|
|`ENGINEHOST `|`File Size (bytes) `|`131072 `|
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
%mp_dsmeta(sashelp.class,outds=work.mymeta)
|
||||||
|
proc print data=work.mymeta;
|
||||||
|
run;
|
||||||
|
|
||||||
|
For more details on creating datasets from PROC CONTENTS check out this
|
||||||
|
excellent [paper](
|
||||||
|
https://support.sas.com/resources/papers/proceedings14/1549-2014.pdf) by
|
||||||
|
[Louise Hadden](https://www.linkedin.com/in/louisehadden/).
|
||||||
|
|
||||||
|
@param libds The library.dataset to export the metadata for
|
||||||
|
@param outds= (work.dsmeta) The output table to contain the metadata
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li mp_dsmeta.test.sas
|
||||||
|
@li mp_getcols.sas
|
||||||
|
@li mp_getdbml.sas
|
||||||
|
@li mp_getddl.sas
|
||||||
|
@li mp_getformats.sas
|
||||||
|
@li mp_getpk.sas
|
||||||
|
@li mp_guesspk.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_dsmeta(libds,outds=work.dsmeta);
|
||||||
|
|
||||||
|
%local ds1 ds2;
|
||||||
|
data;run; %let ds1=&syslast;
|
||||||
|
data;run; %let ds2=&syslast;
|
||||||
|
|
||||||
|
/* setup the ODS capture */
|
||||||
|
ods output attributes=&ds1 enginehost=&ds2;
|
||||||
|
|
||||||
|
/* export the metadata */
|
||||||
|
proc contents data=&libds;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* load it into a single table */
|
||||||
|
data &outds (keep=ods_table name value);
|
||||||
|
length ods_table $10 name label2 label1 label $100
|
||||||
|
value cvalue cvalue1 cvalue2 $1000
|
||||||
|
nvalue nvalue1 nvalue2 8;
|
||||||
|
if _n_=1 then call missing (of _all_);
|
||||||
|
* putlog (_all_)(=);
|
||||||
|
set &ds1 (in=atrs) &ds2 (in=eng);
|
||||||
|
if atrs then do;
|
||||||
|
ods_table='ATTRIBUTES';
|
||||||
|
name=coalescec(label1,label);
|
||||||
|
value=coalescec(cvalue1,cvalue,put(coalesce(nvalue1,nvalue),best.));
|
||||||
|
output;
|
||||||
|
if label2 ne '' then do;
|
||||||
|
name=label2;
|
||||||
|
value=coalescec(cvalue2,put(nvalue2,best.));
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else if eng then do;
|
||||||
|
ods_table='ENGINEHOST';
|
||||||
|
name=coalescec(label1,label);
|
||||||
|
value=coalescec(cvalue1,cvalue,put(coalesce(nvalue1,nvalue),best.));
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
drop table &ds1, &ds2;
|
||||||
|
|
||||||
|
%mend mp_dsmeta;
|
||||||
|
|
||||||
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Checks an input filter table for validity
|
@brief Checks an input filter table for validity
|
||||||
@details Performs checks on the input table to ensure it arrives in the
|
@details Performs checks on the input table to ensure it arrives in the
|
||||||
@@ -8709,7 +8819,7 @@ options
|
|||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to JSON
|
that should be converted to JSON
|
||||||
|
|
||||||
<h4> Related Macros </h4>
|
<h4> Related Files </h4>
|
||||||
@li mp_ds2fmtds.sas
|
@li mp_ds2fmtds.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@@ -8793,7 +8903,7 @@ options
|
|||||||
call symputx(cats('label',_n_),coalescec(label,name),'l');
|
call symputx(cats('label',_n_),coalescec(label,name),'l');
|
||||||
/* overwritten when fmt=Y and a custom format exists in catalog */
|
/* overwritten when fmt=Y and a custom format exists in catalog */
|
||||||
if typelong='num' then call symputx(cats('fmtlen',_n_),200,'l');
|
if typelong='num' then call symputx(cats('fmtlen',_n_),200,'l');
|
||||||
else call symputx(cats('fmtlen',_n_),min(32767,ceil((length+3)*1.5)),'l');
|
else call symputx(cats('fmtlen',_n_),min(32767,ceil((length+10)*1.5)),'l');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
%let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
@@ -8849,15 +8959,15 @@ options
|
|||||||
%let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
%let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
proc sql noprint;
|
proc sql noprint;
|
||||||
create table &tmpds1 as
|
create table &tmpds1 as
|
||||||
select cats(libname,'.',memname) as fmtcat,
|
select cats(libname,'.',memname) as FMTCAT,
|
||||||
fmtname
|
FMTNAME
|
||||||
from dictionary.formats
|
from dictionary.formats
|
||||||
where fmttype='F' and libname is not null
|
where fmttype='F' and libname is not null
|
||||||
and fmtname in (select format from &colinfo where format is not null)
|
and fmtname in (select format from &colinfo where format is not null)
|
||||||
order by 1;
|
order by 1;
|
||||||
create table &tmpds2(
|
create table &tmpds2(
|
||||||
FMTNAME char(32),
|
FMTNAME char(32),
|
||||||
MAX num length=3
|
LENGTH num
|
||||||
);
|
);
|
||||||
%local catlist cat fmtlist i;
|
%local catlist cat fmtlist i;
|
||||||
select distinct fmtcat into: catlist separated by ' ' from &tmpds1;
|
select distinct fmtcat into: catlist separated by ' ' from &tmpds1;
|
||||||
@@ -8866,16 +8976,16 @@ options
|
|||||||
proc sql;
|
proc sql;
|
||||||
select distinct fmtname into: fmtlist separated by ' '
|
select distinct fmtname into: fmtlist separated by ' '
|
||||||
from &tmpds1 where fmtcat="&cat";
|
from &tmpds1 where fmtcat="&cat";
|
||||||
proc format lib=&cat cntlout=&tmpds3(keep=fmtname max);
|
proc format lib=&cat cntlout=&tmpds3(keep=fmtname length);
|
||||||
select &fmtlist;
|
select &fmtlist;
|
||||||
run;
|
run;
|
||||||
proc sql;
|
proc sql;
|
||||||
insert into &tmpds2 select distinct fmtname,max from &tmpds3;
|
insert into &tmpds2 select distinct fmtname,length from &tmpds3;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
create table &tmpds4 as
|
create table &tmpds4 as
|
||||||
select a.*, b.max as maxw
|
select a.*, b.length as MAXW
|
||||||
from &colinfo a
|
from &colinfo a
|
||||||
left join &tmpds2 b
|
left join &tmpds2 b
|
||||||
on cats(a.format)=cats(upcase(b.fmtname))
|
on cats(a.format)=cats(upcase(b.fmtname))
|
||||||
@@ -8886,7 +8996,7 @@ options
|
|||||||
call symputx(
|
call symputx(
|
||||||
cats('fmtlen',_n_),
|
cats('fmtlen',_n_),
|
||||||
/* vars need extra padding due to JSON escaping of special chars */
|
/* vars need extra padding due to JSON escaping of special chars */
|
||||||
min(32767,ceil((max(length,maxw)+3)*1.5))
|
min(32767,ceil((max(length,maxw)+10)*1.5))
|
||||||
,'l'
|
,'l'
|
||||||
);
|
);
|
||||||
run;
|
run;
|
||||||
@@ -8961,7 +9071,7 @@ options
|
|||||||
format _numeric_ bart.;
|
format _numeric_ bart.;
|
||||||
%do i=1 %to &numcols;
|
%do i=1 %to &numcols;
|
||||||
%if &&typelong&i=char or &fmt=Y %then %do;
|
%if &&typelong&i=char or &fmt=Y %then %do;
|
||||||
if findc(&&name&i,'"\'!!'0A0D09000E0F01021011'x) then do;
|
if findc(&&name&i,'"\'!!'0A0D09000E0F010210111A'x) then do;
|
||||||
&&name&i='"'!!trim(
|
&&name&i='"'!!trim(
|
||||||
prxchange('s/"/\\"/',-1, /* double quote */
|
prxchange('s/"/\\"/',-1, /* double quote */
|
||||||
prxchange('s/\x0A/\n/',-1, /* new line */
|
prxchange('s/\x0A/\n/',-1, /* new line */
|
||||||
@@ -8974,8 +9084,9 @@ options
|
|||||||
prxchange('s/\x02/\\u0002/',-1, /* STX */
|
prxchange('s/\x02/\\u0002/',-1, /* STX */
|
||||||
prxchange('s/\x10/\\u0010/',-1, /* DLE */
|
prxchange('s/\x10/\\u0010/',-1, /* DLE */
|
||||||
prxchange('s/\x11/\\u0011/',-1, /* DC1 */
|
prxchange('s/\x11/\\u0011/',-1, /* DC1 */
|
||||||
|
prxchange('s/\x1A/\\u001A/',-1, /* SUB */
|
||||||
prxchange('s/\\/\\\\/',-1,&&name&i)
|
prxchange('s/\\/\\\\/',-1,&&name&i)
|
||||||
))))))))))))!!'"';
|
)))))))))))))!!'"';
|
||||||
end;
|
end;
|
||||||
else &&name&i=quote(cats(&&name&i));
|
else &&name&i=quote(cats(&&name&i));
|
||||||
%end;
|
%end;
|
||||||
@@ -15288,7 +15399,7 @@ data _null_;
|
|||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+10)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
@@ -15344,15 +15455,15 @@ data _null_;
|
|||||||
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
put ' proc sql noprint; ';
|
put ' proc sql noprint; ';
|
||||||
put ' create table &tmpds1 as ';
|
put ' create table &tmpds1 as ';
|
||||||
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
put ' select cats(libname,''.'',memname) as FMTCAT, ';
|
||||||
put ' fmtname ';
|
put ' FMTNAME ';
|
||||||
put ' from dictionary.formats ';
|
put ' from dictionary.formats ';
|
||||||
put ' where fmttype=''F'' and libname is not null ';
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
put ' order by 1; ';
|
put ' order by 1; ';
|
||||||
put ' create table &tmpds2( ';
|
put ' create table &tmpds2( ';
|
||||||
put ' FMTNAME char(32), ';
|
put ' FMTNAME char(32), ';
|
||||||
put ' MAX num length=3 ';
|
put ' LENGTH num ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' %local catlist cat fmtlist i; ';
|
put ' %local catlist cat fmtlist i; ';
|
||||||
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
@@ -15361,16 +15472,16 @@ data _null_;
|
|||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
put ' from &tmpds1 where fmtcat="&cat"; ';
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname max); ';
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
put ' select &fmtlist; ';
|
put ' select &fmtlist; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' insert into &tmpds2 select distinct fmtname,max from &tmpds3; ';
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' create table &tmpds4 as ';
|
put ' create table &tmpds4 as ';
|
||||||
put ' select a.*, b.max as maxw ';
|
put ' select a.*, b.length as MAXW ';
|
||||||
put ' from &colinfo a ';
|
put ' from &colinfo a ';
|
||||||
put ' left join &tmpds2 b ';
|
put ' left join &tmpds2 b ';
|
||||||
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
@@ -15381,7 +15492,7 @@ data _null_;
|
|||||||
put ' call symputx( ';
|
put ' call symputx( ';
|
||||||
put ' cats(''fmtlen'',_n_), ';
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
put ' min(32767,ceil((max(length,maxw)+10)*1.5)) ';
|
||||||
put ' ,''l'' ';
|
put ' ,''l'' ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -15456,7 +15567,7 @@ data _null_;
|
|||||||
put ' format _numeric_ bart.; ';
|
put ' format _numeric_ bart.; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F01021011''x) then do; ';
|
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F010210111A''x) then do; ';
|
||||||
put ' &&name&i=''"''!!trim( ';
|
put ' &&name&i=''"''!!trim( ';
|
||||||
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
||||||
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
||||||
@@ -15469,8 +15580,9 @@ data _null_;
|
|||||||
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
||||||
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
||||||
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
||||||
|
put ' prxchange(''s/\x1A/\\u001A/'',-1, /* SUB */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' ))))))))))))!!''"''; ';
|
put ' )))))))))))))!!''"''; ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else &&name&i=quote(cats(&&name&i)); ';
|
put ' else &&name&i=quote(cats(&&name&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -15566,7 +15678,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
||||||
put ' ,showmeta=N,maxobs=MAX ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||||
put ' sasjs_tables; ';
|
put ' sasjs_tables; ';
|
||||||
@@ -15639,8 +15751,8 @@ data _null_;
|
|||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' /* To avoid issues with _webout on EBI we use a temporary file */ ';
|
put ' /* To avoid issues with _webout on EBI we use a temporary file */ ';
|
||||||
put ' filename _sjsref temp lrecl=131068; ';
|
put ' filename _sjsref temp lrecl=131068; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* if debug mode, send back first 10 records of each work table also */ ';
|
put ' /* if debug mode, send back first XX records of each work table also */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -15664,7 +15776,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10 ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file _sjsref mod encoding=''utf-8''; ';
|
put ' data _null_; file _sjsref mod encoding=''utf-8''; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -17657,6 +17771,73 @@ filename __getdoc clear;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend mm_getstpcode;
|
%mend mm_getstpcode;
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Get the properties of a Stored Process
|
||||||
|
@details Extracts various properties and creates an output table in the
|
||||||
|
structure below:
|
||||||
|
|
||||||
|
|STP_URI:$200.|SERVERCONTEXT:$200.|STOREDPROCESSCONFIGURATION:$1000.|SOURCECODE_FIRST32K:$32767.|PATH:$76.|
|
||||||
|
|---|---|---|---|---|
|
||||||
|
|`A5DN9TDQ.BH0000C8 `|`SASApp `|`<?xml version="1.0" encoding="UTF-8"?><StoredProcess><ServerContext LogicalServerType="Sps" OtherAllowed="false"/><ResultCapabilities Package="false" Streaming="true"/><OutputParameters/></StoredProcess> `|`%put first 32767 bytes of code; `|`/path/to/my/stp`|
|
||||||
|
|
||||||
|
@param [in] pgm The metadata path of the Stored Process
|
||||||
|
@param [out] outds= (work.mm_getstpinfo) The output table to create
|
||||||
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li mm_getstpcode.sas
|
||||||
|
@li mm_getstps.sas
|
||||||
|
@li mm_createstp.sas
|
||||||
|
@li mm_deletestp.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mm_getstpinfo(pgm
|
||||||
|
,outds=work.mm_getstpinfo
|
||||||
|
,mDebug=0
|
||||||
|
);
|
||||||
|
|
||||||
|
%local mD;
|
||||||
|
%if &mDebug=1 %then %let mD=;
|
||||||
|
%else %let mD=%str(*);
|
||||||
|
%&mD.put Executing &sysmacroname..sas;
|
||||||
|
%&mD.put _local_;
|
||||||
|
|
||||||
|
data &outds;
|
||||||
|
length type stp_uri tsuri servercontext value $200
|
||||||
|
StoredProcessConfiguration $1000 sourcecode_first32k $32767;
|
||||||
|
keep path stp_uri sourcecode_first32k StoredProcessConfiguration
|
||||||
|
servercontext;
|
||||||
|
call missing (of _all_);
|
||||||
|
path="&pgm(StoredProcess)";
|
||||||
|
/* first, find the STP ID */
|
||||||
|
if metadata_pathobj("",path,"StoredProcess",type,stp_uri)>0 then do;
|
||||||
|
/* get attributes */
|
||||||
|
cnt=1;
|
||||||
|
do while (metadata_getnasn(stp_uri,"Notes",cnt,tsuri)>0);
|
||||||
|
rc1=metadata_getattr(tsuri,"Name",value);
|
||||||
|
&mD.put tsuri= value=;
|
||||||
|
if value="SourceCode" then do;
|
||||||
|
rc2=metadata_getattr(tsuri,"StoredText",sourcecode_first32k);
|
||||||
|
end;
|
||||||
|
else if value="Stored Process" then do;
|
||||||
|
rc3=metadata_getattr(tsuri,"StoredText",StoredProcessConfiguration);
|
||||||
|
end;
|
||||||
|
cnt+1;
|
||||||
|
end;
|
||||||
|
/* get context (should only be one) */
|
||||||
|
rc4=metadata_getnasn(stp_uri,"ComputeLocations",1,tsuri);
|
||||||
|
rc5=metadata_getattr(tsuri,"Name",servercontext);
|
||||||
|
end;
|
||||||
|
else do;
|
||||||
|
put "%str(ERR)OR: could not find " path;
|
||||||
|
put (_all_)(=);
|
||||||
|
end;
|
||||||
|
&md.put (_all_)(=);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mend mm_getstpinfo ;
|
||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Returns a dataset with all Stored Processes, or just those in a
|
@brief Returns a dataset with all Stored Processes, or just those in a
|
||||||
@@ -19125,6 +19306,9 @@ run;
|
|||||||
such as the column formats and types. The metadata is contained inside an
|
such as the column formats and types. The metadata is contained inside an
|
||||||
object with the same name as the table but prefixed with a dollar sign - ie,
|
object with the same name as the table but prefixed with a dollar sign - ie,
|
||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to output JSON
|
that should be converted to output JSON
|
||||||
|
|
||||||
@@ -19140,7 +19324,7 @@ run;
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
||||||
,showmeta=N,maxobs=MAX
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
sasjs_tables;
|
sasjs_tables;
|
||||||
@@ -19213,8 +19397,8 @@ run;
|
|||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
/* To avoid issues with _webout on EBI we use a temporary file */
|
/* To avoid issues with _webout on EBI we use a temporary file */
|
||||||
filename _sjsref temp lrecl=131068;
|
filename _sjsref temp lrecl=131068;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* if debug mode, send back first 10 records of each work table also */
|
/* if debug mode, send back first XX records of each work table also */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -19238,7 +19422,9 @@ run;
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file _sjsref mod encoding='utf-8';
|
data _null_; file _sjsref mod encoding='utf-8';
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
@@ -20235,7 +20421,7 @@ data _null_;
|
|||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+10)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
@@ -20291,15 +20477,15 @@ data _null_;
|
|||||||
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
put ' proc sql noprint; ';
|
put ' proc sql noprint; ';
|
||||||
put ' create table &tmpds1 as ';
|
put ' create table &tmpds1 as ';
|
||||||
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
put ' select cats(libname,''.'',memname) as FMTCAT, ';
|
||||||
put ' fmtname ';
|
put ' FMTNAME ';
|
||||||
put ' from dictionary.formats ';
|
put ' from dictionary.formats ';
|
||||||
put ' where fmttype=''F'' and libname is not null ';
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
put ' order by 1; ';
|
put ' order by 1; ';
|
||||||
put ' create table &tmpds2( ';
|
put ' create table &tmpds2( ';
|
||||||
put ' FMTNAME char(32), ';
|
put ' FMTNAME char(32), ';
|
||||||
put ' MAX num length=3 ';
|
put ' LENGTH num ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' %local catlist cat fmtlist i; ';
|
put ' %local catlist cat fmtlist i; ';
|
||||||
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
@@ -20308,16 +20494,16 @@ data _null_;
|
|||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
put ' from &tmpds1 where fmtcat="&cat"; ';
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname max); ';
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
put ' select &fmtlist; ';
|
put ' select &fmtlist; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' insert into &tmpds2 select distinct fmtname,max from &tmpds3; ';
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' create table &tmpds4 as ';
|
put ' create table &tmpds4 as ';
|
||||||
put ' select a.*, b.max as maxw ';
|
put ' select a.*, b.length as MAXW ';
|
||||||
put ' from &colinfo a ';
|
put ' from &colinfo a ';
|
||||||
put ' left join &tmpds2 b ';
|
put ' left join &tmpds2 b ';
|
||||||
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
@@ -20328,7 +20514,7 @@ data _null_;
|
|||||||
put ' call symputx( ';
|
put ' call symputx( ';
|
||||||
put ' cats(''fmtlen'',_n_), ';
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
put ' min(32767,ceil((max(length,maxw)+10)*1.5)) ';
|
||||||
put ' ,''l'' ';
|
put ' ,''l'' ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -20403,7 +20589,7 @@ data _null_;
|
|||||||
put ' format _numeric_ bart.; ';
|
put ' format _numeric_ bart.; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F01021011''x) then do; ';
|
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F010210111A''x) then do; ';
|
||||||
put ' &&name&i=''"''!!trim( ';
|
put ' &&name&i=''"''!!trim( ';
|
||||||
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
||||||
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
||||||
@@ -20416,8 +20602,9 @@ data _null_;
|
|||||||
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
||||||
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
||||||
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
||||||
|
put ' prxchange(''s/\x1A/\\u001A/'',-1, /* SUB */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' ))))))))))))!!''"''; ';
|
put ' )))))))))))))!!''"''; ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else &&name&i=quote(cats(&&name&i)); ';
|
put ' else &&name&i=quote(cats(&&name&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -20514,7 +20701,7 @@ data _null_;
|
|||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
||||||
put ' ,showmeta=N,maxobs=MAX ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||||
put ' sasjs_tables; ';
|
put ' sasjs_tables; ';
|
||||||
@@ -20577,8 +20764,8 @@ data _null_;
|
|||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* if debug mode, send back first 10 records of each work table also */ ';
|
put ' /* if debug mode, send back first XX records of each work table also */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -20603,7 +20790,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10 ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -21488,6 +21677,9 @@ run;
|
|||||||
such as the column formats and types. The metadata is contained inside an
|
such as the column formats and types. The metadata is contained inside an
|
||||||
object with the same name as the table but prefixed with a dollar sign - ie,
|
object with the same name as the table but prefixed with a dollar sign - ie,
|
||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to output JSON
|
that should be converted to output JSON
|
||||||
|
|
||||||
@@ -21506,7 +21698,7 @@ run;
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
||||||
,showmeta=N,maxobs=MAX
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
sasjs_tables;
|
sasjs_tables;
|
||||||
@@ -21569,8 +21761,8 @@ run;
|
|||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* if debug mode, send back first 10 records of each work table also */
|
/* if debug mode, send back first XX records of each work table also */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -21595,7 +21787,9 @@ run;
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
@@ -22691,7 +22885,7 @@ data _null_;
|
|||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+10)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
@@ -22747,15 +22941,15 @@ data _null_;
|
|||||||
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
put ' proc sql noprint; ';
|
put ' proc sql noprint; ';
|
||||||
put ' create table &tmpds1 as ';
|
put ' create table &tmpds1 as ';
|
||||||
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
put ' select cats(libname,''.'',memname) as FMTCAT, ';
|
||||||
put ' fmtname ';
|
put ' FMTNAME ';
|
||||||
put ' from dictionary.formats ';
|
put ' from dictionary.formats ';
|
||||||
put ' where fmttype=''F'' and libname is not null ';
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
put ' order by 1; ';
|
put ' order by 1; ';
|
||||||
put ' create table &tmpds2( ';
|
put ' create table &tmpds2( ';
|
||||||
put ' FMTNAME char(32), ';
|
put ' FMTNAME char(32), ';
|
||||||
put ' MAX num length=3 ';
|
put ' LENGTH num ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' %local catlist cat fmtlist i; ';
|
put ' %local catlist cat fmtlist i; ';
|
||||||
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
@@ -22764,16 +22958,16 @@ data _null_;
|
|||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
put ' from &tmpds1 where fmtcat="&cat"; ';
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname max); ';
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
put ' select &fmtlist; ';
|
put ' select &fmtlist; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' insert into &tmpds2 select distinct fmtname,max from &tmpds3; ';
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' create table &tmpds4 as ';
|
put ' create table &tmpds4 as ';
|
||||||
put ' select a.*, b.max as maxw ';
|
put ' select a.*, b.length as MAXW ';
|
||||||
put ' from &colinfo a ';
|
put ' from &colinfo a ';
|
||||||
put ' left join &tmpds2 b ';
|
put ' left join &tmpds2 b ';
|
||||||
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
@@ -22784,7 +22978,7 @@ data _null_;
|
|||||||
put ' call symputx( ';
|
put ' call symputx( ';
|
||||||
put ' cats(''fmtlen'',_n_), ';
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
put ' min(32767,ceil((max(length,maxw)+10)*1.5)) ';
|
||||||
put ' ,''l'' ';
|
put ' ,''l'' ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -22859,7 +23053,7 @@ data _null_;
|
|||||||
put ' format _numeric_ bart.; ';
|
put ' format _numeric_ bart.; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F01021011''x) then do; ';
|
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F010210111A''x) then do; ';
|
||||||
put ' &&name&i=''"''!!trim( ';
|
put ' &&name&i=''"''!!trim( ';
|
||||||
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
||||||
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
||||||
@@ -22872,8 +23066,9 @@ data _null_;
|
|||||||
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
||||||
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
||||||
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
||||||
|
put ' prxchange(''s/\x1A/\\u001A/'',-1, /* SUB */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' ))))))))))))!!''"''; ';
|
put ' )))))))))))))!!''"''; ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else &&name&i=quote(cats(&&name&i)); ';
|
put ' else &&name&i=quote(cats(&&name&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -22969,7 +23164,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL ';
|
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL ';
|
||||||
put ' ,showmeta=N,maxobs=MAX ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
||||||
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
||||||
@@ -23076,8 +23271,8 @@ data _null_;
|
|||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* send back first 10 records of each work table for debugging */ ';
|
put ' /* send back first XX records of each work table for debugging */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -23100,7 +23295,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file &fref mod;put "}"; ';
|
put ' data _null_; file &fref mod;put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' data _null_; file &fref mod;put "}";run; ';
|
put ' data _null_; file &fref mod;put "}";run; ';
|
||||||
@@ -26757,6 +26954,9 @@ filename &fref1 clear;
|
|||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to output JSON
|
that should be converted to output JSON
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_jsonout.sas
|
@li mp_jsonout.sas
|
||||||
@@ -26771,7 +26971,7 @@ filename &fref1 clear;
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL
|
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL
|
||||||
,showmeta=N,maxobs=MAX
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||||
sasjs_tables SYS_JES_JOB_URI;
|
sasjs_tables SYS_JES_JOB_URI;
|
||||||
@@ -26878,8 +27078,8 @@ filename &fref1 clear;
|
|||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* send back first 10 records of each work table for debugging */
|
/* send back first XX records of each work table for debugging */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -26902,7 +27102,9 @@ filename &fref1 clear;
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file &fref mod;put "}";
|
data _null_; file &fref mod;put "}";
|
||||||
%end;
|
%end;
|
||||||
data _null_; file &fref mod;put "}";run;
|
data _null_; file &fref mod;put "}";run;
|
||||||
|
|||||||
110
base/mp_dsmeta.sas
Normal file
110
base/mp_dsmeta.sas
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Export dataset metadata to a single output table
|
||||||
|
@details Exports the dataset attributes and enginehost information, then
|
||||||
|
converts the datasets into a single output table in the following format:
|
||||||
|
|
||||||
|
|ODS_TABLE:$10.|NAME:$100.|VALUE:$1000.|
|
||||||
|
|---|---|---|
|
||||||
|
|`ATTRIBUTES `|`Data Set Name `|`SASHELP.CLASS `|
|
||||||
|
|`ATTRIBUTES `|`Observations `|`19 `|
|
||||||
|
|`ATTRIBUTES `|`Member Type `|`DATA `|
|
||||||
|
|`ATTRIBUTES `|`Variables `|`5 `|
|
||||||
|
|`ATTRIBUTES `|`Engine `|`V9 `|
|
||||||
|
|`ATTRIBUTES `|`Indexes `|`0 `|
|
||||||
|
|`ATTRIBUTES `|`Created `|`06/08/2020 00:59:14 `|
|
||||||
|
|`ATTRIBUTES `|`Observation Length `|`40 `|
|
||||||
|
|`ATTRIBUTES `|`Last Modified `|`06/08/2020 00:59:14 `|
|
||||||
|
|`ATTRIBUTES `|`Deleted Observations `|`0 `|
|
||||||
|
|`ATTRIBUTES `|`Protection `|`. `|
|
||||||
|
|`ATTRIBUTES `|`Compressed `|`NO `|
|
||||||
|
|`ATTRIBUTES `|`Data Set Type `|`. `|
|
||||||
|
|`ATTRIBUTES `|`Sorted `|`NO `|
|
||||||
|
|`ATTRIBUTES `|`Label `|`Student Data `|
|
||||||
|
|`ATTRIBUTES `|`Data Representation `|`SOLARIS_X86_64, LINUX_X86_64, ALPHA_TRU64, LINUX_IA64 `|
|
||||||
|
|`ATTRIBUTES `|`Encoding `|`us-ascii ASCII (ANSI) `|
|
||||||
|
|`ENGINEHOST `|`Data Set Page Size `|`65536 `|
|
||||||
|
|`ENGINEHOST `|`Number of Data Set Pages `|`1 `|
|
||||||
|
|`ENGINEHOST `|`First Data Page `|`1 `|
|
||||||
|
|`ENGINEHOST `|`Max Obs per Page `|`1632 `|
|
||||||
|
|`ENGINEHOST `|`Obs in First Data Page `|`19 `|
|
||||||
|
|`ENGINEHOST `|`Number of Data Set Repairs `|`0 `|
|
||||||
|
|`ENGINEHOST `|`Filename `|`/opt/sas/sas9/SASHome/SASFoundation/9.4/sashelp/class.sas7bdat `|
|
||||||
|
|`ENGINEHOST `|`Release Created `|`9.0401M7 `|
|
||||||
|
|`ENGINEHOST `|`Host Created `|`Linux `|
|
||||||
|
|`ENGINEHOST `|`Inode Number `|`28314616 `|
|
||||||
|
|`ENGINEHOST `|`Access Permission `|`rw-r--r-- `|
|
||||||
|
|`ENGINEHOST `|`Owner Name `|`sas `|
|
||||||
|
|`ENGINEHOST `|`File Size `|`128KB `|
|
||||||
|
|`ENGINEHOST `|`File Size (bytes) `|`131072 `|
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
%mp_dsmeta(sashelp.class,outds=work.mymeta)
|
||||||
|
proc print data=work.mymeta;
|
||||||
|
run;
|
||||||
|
|
||||||
|
For more details on creating datasets from PROC CONTENTS check out this
|
||||||
|
excellent [paper](
|
||||||
|
https://support.sas.com/resources/papers/proceedings14/1549-2014.pdf) by
|
||||||
|
[Louise Hadden](https://www.linkedin.com/in/louisehadden/).
|
||||||
|
|
||||||
|
@param libds The library.dataset to export the metadata for
|
||||||
|
@param outds= (work.dsmeta) The output table to contain the metadata
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li mp_dsmeta.test.sas
|
||||||
|
@li mp_getcols.sas
|
||||||
|
@li mp_getdbml.sas
|
||||||
|
@li mp_getddl.sas
|
||||||
|
@li mp_getformats.sas
|
||||||
|
@li mp_getpk.sas
|
||||||
|
@li mp_guesspk.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_dsmeta(libds,outds=work.dsmeta);
|
||||||
|
|
||||||
|
%local ds1 ds2;
|
||||||
|
data;run; %let ds1=&syslast;
|
||||||
|
data;run; %let ds2=&syslast;
|
||||||
|
|
||||||
|
/* setup the ODS capture */
|
||||||
|
ods output attributes=&ds1 enginehost=&ds2;
|
||||||
|
|
||||||
|
/* export the metadata */
|
||||||
|
proc contents data=&libds;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* load it into a single table */
|
||||||
|
data &outds (keep=ods_table name value);
|
||||||
|
length ods_table $10 name label2 label1 label $100
|
||||||
|
value cvalue cvalue1 cvalue2 $1000
|
||||||
|
nvalue nvalue1 nvalue2 8;
|
||||||
|
if _n_=1 then call missing (of _all_);
|
||||||
|
* putlog (_all_)(=);
|
||||||
|
set &ds1 (in=atrs) &ds2 (in=eng);
|
||||||
|
if atrs then do;
|
||||||
|
ods_table='ATTRIBUTES';
|
||||||
|
name=coalescec(label1,label);
|
||||||
|
value=coalescec(cvalue1,cvalue,put(coalesce(nvalue1,nvalue),best.));
|
||||||
|
output;
|
||||||
|
if label2 ne '' then do;
|
||||||
|
name=label2;
|
||||||
|
value=coalescec(cvalue2,put(nvalue2,best.));
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else if eng then do;
|
||||||
|
ods_table='ENGINEHOST';
|
||||||
|
name=coalescec(label1,label);
|
||||||
|
value=coalescec(cvalue1,cvalue,put(coalesce(nvalue1,nvalue),best.));
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
drop table &ds1, &ds2;
|
||||||
|
|
||||||
|
%mend mp_dsmeta;
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to JSON
|
that should be converted to JSON
|
||||||
|
|
||||||
<h4> Related Macros </h4>
|
<h4> Related Files </h4>
|
||||||
@li mp_ds2fmtds.sas
|
@li mp_ds2fmtds.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
call symputx(cats('label',_n_),coalescec(label,name),'l');
|
call symputx(cats('label',_n_),coalescec(label,name),'l');
|
||||||
/* overwritten when fmt=Y and a custom format exists in catalog */
|
/* overwritten when fmt=Y and a custom format exists in catalog */
|
||||||
if typelong='num' then call symputx(cats('fmtlen',_n_),200,'l');
|
if typelong='num' then call symputx(cats('fmtlen',_n_),200,'l');
|
||||||
else call symputx(cats('fmtlen',_n_),min(32767,ceil((length+3)*1.5)),'l');
|
else call symputx(cats('fmtlen',_n_),min(32767,ceil((length+10)*1.5)),'l');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
%let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
@@ -202,15 +202,15 @@
|
|||||||
%let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
%let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
proc sql noprint;
|
proc sql noprint;
|
||||||
create table &tmpds1 as
|
create table &tmpds1 as
|
||||||
select cats(libname,'.',memname) as fmtcat,
|
select cats(libname,'.',memname) as FMTCAT,
|
||||||
fmtname
|
FMTNAME
|
||||||
from dictionary.formats
|
from dictionary.formats
|
||||||
where fmttype='F' and libname is not null
|
where fmttype='F' and libname is not null
|
||||||
and fmtname in (select format from &colinfo where format is not null)
|
and fmtname in (select format from &colinfo where format is not null)
|
||||||
order by 1;
|
order by 1;
|
||||||
create table &tmpds2(
|
create table &tmpds2(
|
||||||
FMTNAME char(32),
|
FMTNAME char(32),
|
||||||
MAX num length=3
|
LENGTH num
|
||||||
);
|
);
|
||||||
%local catlist cat fmtlist i;
|
%local catlist cat fmtlist i;
|
||||||
select distinct fmtcat into: catlist separated by ' ' from &tmpds1;
|
select distinct fmtcat into: catlist separated by ' ' from &tmpds1;
|
||||||
@@ -219,16 +219,16 @@
|
|||||||
proc sql;
|
proc sql;
|
||||||
select distinct fmtname into: fmtlist separated by ' '
|
select distinct fmtname into: fmtlist separated by ' '
|
||||||
from &tmpds1 where fmtcat="&cat";
|
from &tmpds1 where fmtcat="&cat";
|
||||||
proc format lib=&cat cntlout=&tmpds3(keep=fmtname max);
|
proc format lib=&cat cntlout=&tmpds3(keep=fmtname length);
|
||||||
select &fmtlist;
|
select &fmtlist;
|
||||||
run;
|
run;
|
||||||
proc sql;
|
proc sql;
|
||||||
insert into &tmpds2 select distinct fmtname,max from &tmpds3;
|
insert into &tmpds2 select distinct fmtname,length from &tmpds3;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
create table &tmpds4 as
|
create table &tmpds4 as
|
||||||
select a.*, b.max as maxw
|
select a.*, b.length as MAXW
|
||||||
from &colinfo a
|
from &colinfo a
|
||||||
left join &tmpds2 b
|
left join &tmpds2 b
|
||||||
on cats(a.format)=cats(upcase(b.fmtname))
|
on cats(a.format)=cats(upcase(b.fmtname))
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
call symputx(
|
call symputx(
|
||||||
cats('fmtlen',_n_),
|
cats('fmtlen',_n_),
|
||||||
/* vars need extra padding due to JSON escaping of special chars */
|
/* vars need extra padding due to JSON escaping of special chars */
|
||||||
min(32767,ceil((max(length,maxw)+3)*1.5))
|
min(32767,ceil((max(length,maxw)+10)*1.5))
|
||||||
,'l'
|
,'l'
|
||||||
);
|
);
|
||||||
run;
|
run;
|
||||||
@@ -314,7 +314,7 @@
|
|||||||
format _numeric_ bart.;
|
format _numeric_ bart.;
|
||||||
%do i=1 %to &numcols;
|
%do i=1 %to &numcols;
|
||||||
%if &&typelong&i=char or &fmt=Y %then %do;
|
%if &&typelong&i=char or &fmt=Y %then %do;
|
||||||
if findc(&&name&i,'"\'!!'0A0D09000E0F01021011'x) then do;
|
if findc(&&name&i,'"\'!!'0A0D09000E0F010210111A'x) then do;
|
||||||
&&name&i='"'!!trim(
|
&&name&i='"'!!trim(
|
||||||
prxchange('s/"/\\"/',-1, /* double quote */
|
prxchange('s/"/\\"/',-1, /* double quote */
|
||||||
prxchange('s/\x0A/\n/',-1, /* new line */
|
prxchange('s/\x0A/\n/',-1, /* new line */
|
||||||
@@ -327,8 +327,9 @@
|
|||||||
prxchange('s/\x02/\\u0002/',-1, /* STX */
|
prxchange('s/\x02/\\u0002/',-1, /* STX */
|
||||||
prxchange('s/\x10/\\u0010/',-1, /* DLE */
|
prxchange('s/\x10/\\u0010/',-1, /* DLE */
|
||||||
prxchange('s/\x11/\\u0011/',-1, /* DC1 */
|
prxchange('s/\x11/\\u0011/',-1, /* DC1 */
|
||||||
|
prxchange('s/\x1A/\\u001A/',-1, /* SUB */
|
||||||
prxchange('s/\\/\\\\/',-1,&&name&i)
|
prxchange('s/\\/\\\\/',-1,&&name&i)
|
||||||
))))))))))))!!'"';
|
)))))))))))))!!'"';
|
||||||
end;
|
end;
|
||||||
else &&name&i=quote(cats(&&name&i));
|
else &&name&i=quote(cats(&&name&i));
|
||||||
%end;
|
%end;
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ data _null_;
|
|||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+10)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
@@ -225,15 +225,15 @@ data _null_;
|
|||||||
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
put ' proc sql noprint; ';
|
put ' proc sql noprint; ';
|
||||||
put ' create table &tmpds1 as ';
|
put ' create table &tmpds1 as ';
|
||||||
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
put ' select cats(libname,''.'',memname) as FMTCAT, ';
|
||||||
put ' fmtname ';
|
put ' FMTNAME ';
|
||||||
put ' from dictionary.formats ';
|
put ' from dictionary.formats ';
|
||||||
put ' where fmttype=''F'' and libname is not null ';
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
put ' order by 1; ';
|
put ' order by 1; ';
|
||||||
put ' create table &tmpds2( ';
|
put ' create table &tmpds2( ';
|
||||||
put ' FMTNAME char(32), ';
|
put ' FMTNAME char(32), ';
|
||||||
put ' MAX num length=3 ';
|
put ' LENGTH num ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' %local catlist cat fmtlist i; ';
|
put ' %local catlist cat fmtlist i; ';
|
||||||
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
@@ -242,16 +242,16 @@ data _null_;
|
|||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
put ' from &tmpds1 where fmtcat="&cat"; ';
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname max); ';
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
put ' select &fmtlist; ';
|
put ' select &fmtlist; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' insert into &tmpds2 select distinct fmtname,max from &tmpds3; ';
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' create table &tmpds4 as ';
|
put ' create table &tmpds4 as ';
|
||||||
put ' select a.*, b.max as maxw ';
|
put ' select a.*, b.length as MAXW ';
|
||||||
put ' from &colinfo a ';
|
put ' from &colinfo a ';
|
||||||
put ' left join &tmpds2 b ';
|
put ' left join &tmpds2 b ';
|
||||||
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
@@ -262,7 +262,7 @@ data _null_;
|
|||||||
put ' call symputx( ';
|
put ' call symputx( ';
|
||||||
put ' cats(''fmtlen'',_n_), ';
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
put ' min(32767,ceil((max(length,maxw)+10)*1.5)) ';
|
||||||
put ' ,''l'' ';
|
put ' ,''l'' ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -337,7 +337,7 @@ data _null_;
|
|||||||
put ' format _numeric_ bart.; ';
|
put ' format _numeric_ bart.; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F01021011''x) then do; ';
|
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F010210111A''x) then do; ';
|
||||||
put ' &&name&i=''"''!!trim( ';
|
put ' &&name&i=''"''!!trim( ';
|
||||||
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
||||||
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
||||||
@@ -350,8 +350,9 @@ data _null_;
|
|||||||
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
||||||
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
||||||
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
||||||
|
put ' prxchange(''s/\x1A/\\u001A/'',-1, /* SUB */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' ))))))))))))!!''"''; ';
|
put ' )))))))))))))!!''"''; ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else &&name&i=quote(cats(&&name&i)); ';
|
put ' else &&name&i=quote(cats(&&name&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -447,7 +448,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
||||||
put ' ,showmeta=N,maxobs=MAX ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||||
put ' sasjs_tables; ';
|
put ' sasjs_tables; ';
|
||||||
@@ -520,8 +521,8 @@ data _null_;
|
|||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' /* To avoid issues with _webout on EBI we use a temporary file */ ';
|
put ' /* To avoid issues with _webout on EBI we use a temporary file */ ';
|
||||||
put ' filename _sjsref temp lrecl=131068; ';
|
put ' filename _sjsref temp lrecl=131068; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* if debug mode, send back first 10 records of each work table also */ ';
|
put ' /* if debug mode, send back first XX records of each work table also */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -545,7 +546,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10 ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file _sjsref mod encoding=''utf-8''; ';
|
put ' data _null_; file _sjsref mod encoding=''utf-8''; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
|
|||||||
67
meta/mm_getstpinfo.sas
Normal file
67
meta/mm_getstpinfo.sas
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Get the properties of a Stored Process
|
||||||
|
@details Extracts various properties and creates an output table in the
|
||||||
|
structure below:
|
||||||
|
|
||||||
|
|STP_URI:$200.|SERVERCONTEXT:$200.|STOREDPROCESSCONFIGURATION:$1000.|SOURCECODE_FIRST32K:$32767.|PATH:$76.|
|
||||||
|
|---|---|---|---|---|
|
||||||
|
|`A5DN9TDQ.BH0000C8 `|`SASApp `|`<?xml version="1.0" encoding="UTF-8"?><StoredProcess><ServerContext LogicalServerType="Sps" OtherAllowed="false"/><ResultCapabilities Package="false" Streaming="true"/><OutputParameters/></StoredProcess> `|`%put first 32767 bytes of code; `|`/path/to/my/stp`|
|
||||||
|
|
||||||
|
@param [in] pgm The metadata path of the Stored Process
|
||||||
|
@param [out] outds= (work.mm_getstpinfo) The output table to create
|
||||||
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li mm_getstpcode.sas
|
||||||
|
@li mm_getstps.sas
|
||||||
|
@li mm_createstp.sas
|
||||||
|
@li mm_deletestp.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mm_getstpinfo(pgm
|
||||||
|
,outds=work.mm_getstpinfo
|
||||||
|
,mDebug=0
|
||||||
|
);
|
||||||
|
|
||||||
|
%local mD;
|
||||||
|
%if &mDebug=1 %then %let mD=;
|
||||||
|
%else %let mD=%str(*);
|
||||||
|
%&mD.put Executing &sysmacroname..sas;
|
||||||
|
%&mD.put _local_;
|
||||||
|
|
||||||
|
data &outds;
|
||||||
|
length type stp_uri tsuri servercontext value $200
|
||||||
|
StoredProcessConfiguration $1000 sourcecode_first32k $32767;
|
||||||
|
keep path stp_uri sourcecode_first32k StoredProcessConfiguration
|
||||||
|
servercontext;
|
||||||
|
call missing (of _all_);
|
||||||
|
path="&pgm(StoredProcess)";
|
||||||
|
/* first, find the STP ID */
|
||||||
|
if metadata_pathobj("",path,"StoredProcess",type,stp_uri)>0 then do;
|
||||||
|
/* get attributes */
|
||||||
|
cnt=1;
|
||||||
|
do while (metadata_getnasn(stp_uri,"Notes",cnt,tsuri)>0);
|
||||||
|
rc1=metadata_getattr(tsuri,"Name",value);
|
||||||
|
&mD.put tsuri= value=;
|
||||||
|
if value="SourceCode" then do;
|
||||||
|
rc2=metadata_getattr(tsuri,"StoredText",sourcecode_first32k);
|
||||||
|
end;
|
||||||
|
else if value="Stored Process" then do;
|
||||||
|
rc3=metadata_getattr(tsuri,"StoredText",StoredProcessConfiguration);
|
||||||
|
end;
|
||||||
|
cnt+1;
|
||||||
|
end;
|
||||||
|
/* get context (should only be one) */
|
||||||
|
rc4=metadata_getnasn(stp_uri,"ComputeLocations",1,tsuri);
|
||||||
|
rc5=metadata_getattr(tsuri,"Name",servercontext);
|
||||||
|
end;
|
||||||
|
else do;
|
||||||
|
put "%str(ERR)OR: could not find " path;
|
||||||
|
put (_all_)(=);
|
||||||
|
end;
|
||||||
|
&md.put (_all_)(=);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mend mm_getstpinfo ;
|
||||||
@@ -34,6 +34,9 @@
|
|||||||
such as the column formats and types. The metadata is contained inside an
|
such as the column formats and types. The metadata is contained inside an
|
||||||
object with the same name as the table but prefixed with a dollar sign - ie,
|
object with the same name as the table but prefixed with a dollar sign - ie,
|
||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to output JSON
|
that should be converted to output JSON
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
||||||
,showmeta=N,maxobs=MAX
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
sasjs_tables;
|
sasjs_tables;
|
||||||
@@ -122,8 +125,8 @@
|
|||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
/* To avoid issues with _webout on EBI we use a temporary file */
|
/* To avoid issues with _webout on EBI we use a temporary file */
|
||||||
filename _sjsref temp lrecl=131068;
|
filename _sjsref temp lrecl=131068;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* if debug mode, send back first 10 records of each work table also */
|
/* if debug mode, send back first XX records of each work table also */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -147,7 +150,9 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file _sjsref mod encoding='utf-8';
|
data _null_; file _sjsref mod encoding='utf-8';
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ data _null_;
|
|||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+10)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
@@ -226,15 +226,15 @@ data _null_;
|
|||||||
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
put ' proc sql noprint; ';
|
put ' proc sql noprint; ';
|
||||||
put ' create table &tmpds1 as ';
|
put ' create table &tmpds1 as ';
|
||||||
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
put ' select cats(libname,''.'',memname) as FMTCAT, ';
|
||||||
put ' fmtname ';
|
put ' FMTNAME ';
|
||||||
put ' from dictionary.formats ';
|
put ' from dictionary.formats ';
|
||||||
put ' where fmttype=''F'' and libname is not null ';
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
put ' order by 1; ';
|
put ' order by 1; ';
|
||||||
put ' create table &tmpds2( ';
|
put ' create table &tmpds2( ';
|
||||||
put ' FMTNAME char(32), ';
|
put ' FMTNAME char(32), ';
|
||||||
put ' MAX num length=3 ';
|
put ' LENGTH num ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' %local catlist cat fmtlist i; ';
|
put ' %local catlist cat fmtlist i; ';
|
||||||
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
@@ -243,16 +243,16 @@ data _null_;
|
|||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
put ' from &tmpds1 where fmtcat="&cat"; ';
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname max); ';
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
put ' select &fmtlist; ';
|
put ' select &fmtlist; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' insert into &tmpds2 select distinct fmtname,max from &tmpds3; ';
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' create table &tmpds4 as ';
|
put ' create table &tmpds4 as ';
|
||||||
put ' select a.*, b.max as maxw ';
|
put ' select a.*, b.length as MAXW ';
|
||||||
put ' from &colinfo a ';
|
put ' from &colinfo a ';
|
||||||
put ' left join &tmpds2 b ';
|
put ' left join &tmpds2 b ';
|
||||||
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
@@ -263,7 +263,7 @@ data _null_;
|
|||||||
put ' call symputx( ';
|
put ' call symputx( ';
|
||||||
put ' cats(''fmtlen'',_n_), ';
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
put ' min(32767,ceil((max(length,maxw)+10)*1.5)) ';
|
||||||
put ' ,''l'' ';
|
put ' ,''l'' ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -338,7 +338,7 @@ data _null_;
|
|||||||
put ' format _numeric_ bart.; ';
|
put ' format _numeric_ bart.; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F01021011''x) then do; ';
|
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F010210111A''x) then do; ';
|
||||||
put ' &&name&i=''"''!!trim( ';
|
put ' &&name&i=''"''!!trim( ';
|
||||||
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
||||||
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
||||||
@@ -351,8 +351,9 @@ data _null_;
|
|||||||
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
||||||
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
||||||
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
||||||
|
put ' prxchange(''s/\x1A/\\u001A/'',-1, /* SUB */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' ))))))))))))!!''"''; ';
|
put ' )))))))))))))!!''"''; ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else &&name&i=quote(cats(&&name&i)); ';
|
put ' else &&name&i=quote(cats(&&name&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -449,7 +450,7 @@ data _null_;
|
|||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
||||||
put ' ,showmeta=N,maxobs=MAX ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||||
put ' sasjs_tables; ';
|
put ' sasjs_tables; ';
|
||||||
@@ -512,8 +513,8 @@ data _null_;
|
|||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* if debug mode, send back first 10 records of each work table also */ ';
|
put ' /* if debug mode, send back first XX records of each work table also */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -538,7 +539,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10 ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
|
|||||||
@@ -31,6 +31,9 @@
|
|||||||
such as the column formats and types. The metadata is contained inside an
|
such as the column formats and types. The metadata is contained inside an
|
||||||
object with the same name as the table but prefixed with a dollar sign - ie,
|
object with the same name as the table but prefixed with a dollar sign - ie,
|
||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to output JSON
|
that should be converted to output JSON
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
||||||
,showmeta=N,maxobs=MAX
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
sasjs_tables;
|
sasjs_tables;
|
||||||
@@ -112,8 +115,8 @@
|
|||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* if debug mode, send back first 10 records of each work table also */
|
/* if debug mode, send back first XX records of each work table also */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -138,7 +141,9 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
|
|||||||
32
tests/base/mp_dsmeta.test.sas
Normal file
32
tests/base/mp_dsmeta.test.sas
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_dsmeta.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
@li mp_dsmeta.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
data work.Example;
|
||||||
|
set sashelp.vmacro;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mp_dsmeta(work.example,outds=work.test)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
|
proc sql noprint;
|
||||||
|
select count(*) into: nobs from work.test;
|
||||||
|
select count(distinct ods_table) into: tnobs from work.test;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&tnobs=2),
|
||||||
|
desc=Check that both ATTRIBUTES and ENGINEHOST are provided
|
||||||
|
)
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&nobs>10),
|
||||||
|
desc=Check that sufficient details are provided
|
||||||
|
)
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ data _null_;
|
|||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+10)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
@@ -368,15 +368,15 @@ data _null_;
|
|||||||
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
put ' proc sql noprint; ';
|
put ' proc sql noprint; ';
|
||||||
put ' create table &tmpds1 as ';
|
put ' create table &tmpds1 as ';
|
||||||
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
put ' select cats(libname,''.'',memname) as FMTCAT, ';
|
||||||
put ' fmtname ';
|
put ' FMTNAME ';
|
||||||
put ' from dictionary.formats ';
|
put ' from dictionary.formats ';
|
||||||
put ' where fmttype=''F'' and libname is not null ';
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
put ' order by 1; ';
|
put ' order by 1; ';
|
||||||
put ' create table &tmpds2( ';
|
put ' create table &tmpds2( ';
|
||||||
put ' FMTNAME char(32), ';
|
put ' FMTNAME char(32), ';
|
||||||
put ' MAX num length=3 ';
|
put ' LENGTH num ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' %local catlist cat fmtlist i; ';
|
put ' %local catlist cat fmtlist i; ';
|
||||||
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
@@ -385,16 +385,16 @@ data _null_;
|
|||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
put ' from &tmpds1 where fmtcat="&cat"; ';
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname max); ';
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
put ' select &fmtlist; ';
|
put ' select &fmtlist; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' insert into &tmpds2 select distinct fmtname,max from &tmpds3; ';
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc sql; ';
|
put ' proc sql; ';
|
||||||
put ' create table &tmpds4 as ';
|
put ' create table &tmpds4 as ';
|
||||||
put ' select a.*, b.max as maxw ';
|
put ' select a.*, b.length as MAXW ';
|
||||||
put ' from &colinfo a ';
|
put ' from &colinfo a ';
|
||||||
put ' left join &tmpds2 b ';
|
put ' left join &tmpds2 b ';
|
||||||
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
@@ -405,7 +405,7 @@ data _null_;
|
|||||||
put ' call symputx( ';
|
put ' call symputx( ';
|
||||||
put ' cats(''fmtlen'',_n_), ';
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
put ' min(32767,ceil((max(length,maxw)+10)*1.5)) ';
|
||||||
put ' ,''l'' ';
|
put ' ,''l'' ';
|
||||||
put ' ); ';
|
put ' ); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -480,7 +480,7 @@ data _null_;
|
|||||||
put ' format _numeric_ bart.; ';
|
put ' format _numeric_ bart.; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F01021011''x) then do; ';
|
put ' if findc(&&name&i,''"\''!!''0A0D09000E0F010210111A''x) then do; ';
|
||||||
put ' &&name&i=''"''!!trim( ';
|
put ' &&name&i=''"''!!trim( ';
|
||||||
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
put ' prxchange(''s/"/\\"/'',-1, /* double quote */ ';
|
||||||
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
|
||||||
@@ -493,8 +493,9 @@ data _null_;
|
|||||||
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
|
||||||
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
|
||||||
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
|
||||||
|
put ' prxchange(''s/\x1A/\\u001A/'',-1, /* SUB */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' ))))))))))))!!''"''; ';
|
put ' )))))))))))))!!''"''; ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else &&name&i=quote(cats(&&name&i)); ';
|
put ' else &&name&i=quote(cats(&&name&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -590,7 +591,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL ';
|
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL ';
|
||||||
put ' ,showmeta=N,maxobs=MAX ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
||||||
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
||||||
@@ -697,8 +698,8 @@ data _null_;
|
|||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* send back first 10 records of each work table for debugging */ ';
|
put ' /* send back first XX records of each work table for debugging */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -721,7 +722,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file &fref mod;put "}"; ';
|
put ' data _null_; file &fref mod;put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' data _null_; file &fref mod;put "}";run; ';
|
put ' data _null_; file &fref mod;put "}";run; ';
|
||||||
|
|||||||
@@ -35,6 +35,9 @@
|
|||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to output JSON
|
that should be converted to output JSON
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_jsonout.sas
|
@li mp_jsonout.sas
|
||||||
@@ -49,7 +52,7 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL
|
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL
|
||||||
,showmeta=N,maxobs=MAX
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||||
sasjs_tables SYS_JES_JOB_URI;
|
sasjs_tables SYS_JES_JOB_URI;
|
||||||
@@ -156,8 +159,8 @@
|
|||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* send back first 10 records of each work table for debugging */
|
/* send back first XX records of each work table for debugging */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -180,7 +183,9 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file &fref mod;put "}";
|
data _null_; file &fref mod;put "}";
|
||||||
%end;
|
%end;
|
||||||
data _null_; file &fref mod;put "}";run;
|
data _null_; file &fref mod;put "}";run;
|
||||||
|
|||||||
Reference in New Issue
Block a user