From 029c1a29edc4829db299d013b4483139b8558870 Mon Sep 17 00:00:00 2001 From: vrh Date: Tue, 18 Aug 2020 23:09:13 +0200 Subject: [PATCH] feat: xlsx support in mp_streamfile --- all.sas | 142 +++++++++++++++++++++++++++++++++-------- base/mp_streamfile.sas | 14 ++++ 2 files changed, 128 insertions(+), 28 deletions(-) diff --git a/all.sas b/all.sas index aa7a7c4..0cc13f2 100644 --- a/all.sas +++ b/all.sas @@ -2504,35 +2504,52 @@ create table _data_ as separated by ' ' from &syslast ; -quit; + +create table _data_ as + select * from dictionary.indexes + where upcase(libname)="%upcase(&libref)" + %if %length(&ds)>0 %then %do; + and upcase(memname)="%upcase(&ds)" + %end; + order by idxusage, indxname, indxpos + ; +%local idxinfo; %let idxinfo=&syslast; /* Extract all Primary Key and Unique data constraints */ %mp_getconstraints(lib=%upcase(&libref),ds=%upcase(&ds),outds=_data_) %local colconst; %let colconst=&syslast; %macro addConst(); - data _null_; - length ctype $11; - set &colconst (where=(table_name="&curds" and constraint_type in ('PRIMARY','UNIQUE'))) end=last; - file &fref mod; - by constraint_type constraint_name; - if upcase(strip(constraint_type)) = 'PRIMARY' then ctype='PRIMARY KEY'; - else ctype=strip(constraint_type); - %if &flavour=TSQL %then %do; - column_name=catt('[',column_name,']'); - constraint_name=catt('[',constraint_name,']'); - %end; - %else %if &flavour=PGSQL %then %do; - column_name=catt('"',column_name,'"'); - constraint_name=catt('"',constraint_name,'"'); - %end; - if first.constraint_name then do; - put " ,CONSTRAINT " constraint_name ctype "(" ; - put ' ' column_name; - end; - else put ' ,' column_name; - if last.constraint_name then put " )"; - run; + %global constraints_used; + data _null_; + length ctype $11 constraint_name_orig $256 constraints_used $5000; + set &colconst (where=(table_name="&curds" and constraint_type in ('PRIMARY','UNIQUE'))) end=last; + file &fref mod; + by constraint_type constraint_name; + retain constraints_used; + constraint_name_orig=constraint_name; + if upcase(strip(constraint_type)) = 'PRIMARY' then ctype='PRIMARY KEY'; + else ctype=strip(constraint_type); + %if &flavour=TSQL %then %do; + column_name=catt('[',column_name,']'); + constraint_name=catt('[',constraint_name,']'); + %end; + %else %if &flavour=PGSQL %then %do; + column_name=catt('"',column_name,'"'); + constraint_name=catt('"',constraint_name,'"'); + %end; + if first.constraint_name then do; + constraints_used = catx(' ', constraints_used, constraint_name_orig); + put " ,CONSTRAINT " constraint_name ctype "(" ; + put ' ' column_name; + end; + else put ' ,' column_name; + if last.constraint_name then do; + put " )"; + call symput('constraints_used',strip(constraints_used)); + end; + run; + %put &=constraints_used; %mend; data _null_; @@ -2544,13 +2561,13 @@ run; %if &flavour=SAS %then %do; data _null_; file &fref mod; + put "/* SAS Flavour DDL for %upcase(&libref).&curds */"; put "proc sql;"; run; %do x=1 %to %sysfunc(countw(&dsnlist)); %let curds=%scan(&dsnlist,&x); data _null_; file &fref mod; - if _n_ eq 1 then put "/* SAS Flavour DDL for %upcase(&libref).&curds */"; length nm lab $1024; set &colinfo (where=(upcase(memname)="&curds")) end=last; @@ -2578,6 +2595,25 @@ run; file &fref mod; put ');'; run; + + /* Create Unique Indexes, but only if they were not already defined within the Constraints section. */ + data _null_; + *length ds $128; + set &idxinfo (where=(memname="&curds" and unique='yes' and indxname not in (%sysfunc(tranwrd("&constraints_used",%str( ),%str(",")))))); + file &fref mod; + by idxusage indxname; +/* ds=cats(libname,'.',memname); */ + if first.indxname then do; + put 'CREATE UNIQUE INDEX ' indxname "ON &libref..&curds (" ; + put ' ' name ; + end; + else put ' ,' name ; + *else put ' ,' name ; + if last.indxname then do; + put ');'; + end; + run; + /* ods output IntegrityConstraints=ic; proc contents data=testali out2=info; @@ -2627,6 +2663,24 @@ run; /* Extra step for data constraints */ %addConst() + /* Create Unique Indexes, but only if they were not already defined within the Constraints section. */ + data _null_; + *length ds $128; + set &idxinfo (where=(memname="&curds" and unique='yes' and indxname not in (%sysfunc(tranwrd("&constraints_used",%str( ),%str(",")))))); + file &fref mod; + by idxusage indxname; + *ds=cats(libname,'.',memname); + if first.indxname then do; + /* add nonclustered in case of multiple unique indexes */ + put ' ,index [' indxname +(-1) '] UNIQUE NONCLUSTERED ('; + put ' [' name +(-1) ']'; + end; + else put ' ,[' name +(-1) ']'; + if last.indxname then do; + put ' )'; + end; + run; + data _null_; file &fref mod; put ')'; @@ -2701,6 +2755,24 @@ run; put ');'; run; + /* Create Unique Indexes, but only if they were not already defined within the Constraints section. */ + data _null_; + *length ds $128; + set &idxinfo (where=(memname="&curds" and unique='yes' and indxname not in (%sysfunc(tranwrd("&constraints_used",%str( ),%str(",")))))); + file &fref mod; + by idxusage indxname; +/* ds=cats(libname,'.',memname); */ + if first.indxname then do; + put 'CREATE UNIQUE INDEX "' indxname +(-1) '" ' "ON &schema..&curds (" ; + put ' "' name +(-1) '"' ; + end; + else put ' ,"' name +(-1) '"'; + *else put ' ,' name ; + if last.indxname then do; + put ');'; + end; + run; + %end; %end; %if &showlog=YES %then %do; @@ -3860,6 +3932,7 @@ proc sql %end; %end; %else %if &contentype=EXCEL %then %do; + /* suitable for XLS format */ %if &platform=SASMETA %then %do; data _null_; rc=stpsrv_header('Content-type','application/vnd.ms-excel'); @@ -3872,6 +3945,19 @@ proc sql contentdisp="attachment; filename=&outname"; %end; %end; +%else %if &contentype=XLSX %then %do; + %if &platform=SASMETA %then %do; + data _null_; + rc=stpsrv_header('Content-type','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + rc=stpsrv_header('Content-disposition',"attachment; filename=&outname"); + run; + %end; + %else %if &platform=SASVIYA %then %do; + filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.xls' + contenttype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + contentdisp="attachment; filename=&outname"; + %end; +%end; %else %if &contentype=TEXT %then %do; %if &platform=SASMETA %then %do; data _null_; @@ -8018,17 +8104,17 @@ run; Usage: - - get a table id - %mm_gettableid(libref=METALIB,ds=SOMETABLE,outds=iwant) + - get a table id + %mm_gettableid(libref=METALIB,ds=SOMETABLE,outds=iwant) @param libref= The libref to search @param ds= The input dataset to check - @param outds= the dataset to create that contains the `tableuri`` + @param outds= the dataset to create that contains the `tableuri` @param mDebug= set to 1 to show debug messages in the log @returns outds dataset containing `tableuri` and `tablename` - @version 9.2 + @version 9.3 @author Allan Bowe **/ diff --git a/base/mp_streamfile.sas b/base/mp_streamfile.sas index f419e5d..8f79d4e 100644 --- a/base/mp_streamfile.sas +++ b/base/mp_streamfile.sas @@ -47,6 +47,7 @@ %end; %end; %else %if &contentype=EXCEL %then %do; + /* suitable for XLS format */ %if &platform=SASMETA %then %do; data _null_; rc=stpsrv_header('Content-type','application/vnd.ms-excel'); @@ -59,6 +60,19 @@ contentdisp="attachment; filename=&outname"; %end; %end; +%else %if &contentype=XLSX %then %do; + %if &platform=SASMETA %then %do; + data _null_; + rc=stpsrv_header('Content-type','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + rc=stpsrv_header('Content-disposition',"attachment; filename=&outname"); + run; + %end; + %else %if &platform=SASVIYA %then %do; + filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.xls' + contenttype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + contentdisp="attachment; filename=&outname"; + %end; +%end; %else %if &contentype=TEXT %then %do; %if &platform=SASMETA %then %do; data _null_;