1
0
mirror of https://github.com/sasjs/core.git synced 2026-01-05 00:20:05 +00:00

Compare commits

...

11 Commits

Author SHA1 Message Date
Allan Bowe
0fa076cb73 Merge pull request #77 from sasjs/dictfix
fix: ensuring upcase comparisons for dictionary tables
2021-09-27 15:17:48 +03:00
Allan Bowe
6506993704 fix: ensuring upcase comparisons for dictionary tables 2021-09-27 13:04:32 +01:00
Allan Bowe
a69db2ebfb Merge pull request #76 from sasjs/mp_appendfile
feat: mp_appendfile macro for appending 2 or more files together
2021-09-27 14:50:55 +03:00
Allan Bowe
d72ca7cb24 fix: warning in mp_assertcolvals from outobs sql option 2021-09-27 12:30:28 +01:00
Allan Bowe
52dfa7b8f7 feat: mp_appendfile macro for appending 2 or more files together 2021-09-27 11:46:19 +01:00
Allan Bowe
dae03c5730 fix: adding SYSSCPL to mp_abort and webout macros 2021-09-24 17:31:42 +01:00
Allan Bowe
14efe5d3fd chore: removing copyright notice (copy paste error) 2021-09-22 21:10:00 +01:00
Allan Bowe
653244d737 Merge pull request #75 from sasjs/mp_getcols
Mp getcols macro
2021-09-22 19:34:25 +03:00
Allan Bowe
086831b3f5 chore: updating all.sas 2021-09-22 17:20:02 +01:00
Allan Bowe
6eca585fc1 feat: new mp_getcols macro 2021-09-22 17:19:49 +01:00
Allan Bowe
f6ba36fc28 feat: adding more info to result description in mp_assertcolvals 2021-09-22 17:19:29 +01:00
15 changed files with 404 additions and 36 deletions

182
all.sas
View File

@@ -1841,6 +1841,7 @@ Usage:
put ",""SYSERRORTEXT"" : " syserrortext; put ",""SYSERRORTEXT"" : " syserrortext;
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSJOBID"" : ""&sysjobid"" "; put ",""SYSJOBID"" : ""&sysjobid"" ";
put ",""SYSSCPL"" : ""&sysscpl"" ";
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
@@ -1855,7 +1856,7 @@ Usage:
%if "&sysprocessmode " = "SAS Stored Process Server " %then %do; %if "&sysprocessmode " = "SAS Stored Process Server " %then %do;
data _null_; data _null_;
putlog 'stpsrvset program error and syscc'; putlog 'stpsrvset program err and syscc';
rc=stpsrvset('program error', 0); rc=stpsrvset('program error', 0);
call symputx("syscc",0,"g"); call symputx("syscc",0,"g");
run; run;
@@ -1901,6 +1902,62 @@ Usage:
%mend mp_abort; %mend mp_abort;
/** @endcond *//** /** @endcond *//**
@file
@brief Append (concatenate) two or more files.
@details Will append one more more `appendrefs` (filerefs) to a `baseref`.
Uses a binary mechanism, so will work with any file type. For that reason -
use with care! And supply your own trailing carriage returns in each file..
Usage:
filename tmp1 temp;
filename tmp2 temp;
filename tmp3 temp;
data _null_; file tmp1; put 'base file';
data _null_; file tmp2; put 'append1';
data _null_; file tmp3; put 'append2';
run;
%mp_appendfile(baseref=tmp1, appendrefs=tmp2 tmp3)
@param [in] baseref= Fileref of the base file (should exist)
@param [in] appendrefs= One or more filerefs to be appended to the base
fileref. Space separated.
@version 9.2
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mp_binarycopy.sas
**/
%macro mp_appendfile(
baseref=0,
appendrefs=0
)/*/STORE SOURCE*/;
%mp_abort(iftrue= (&baseref=0)
,mac=&sysmacroname
,msg=%str(Baseref NOT specified!)
)
%mp_abort(iftrue= (&appendrefs=0)
,mac=&sysmacroname
,msg=%str(Appendrefs NOT specified!)
)
%local i;
%do i=1 %to %sysfunc(countw(&appendrefs));
%mp_abort(iftrue= (&syscc>0)
,mac=&sysmacroname
,msg=%str(syscc=&syscc)
)
%mp_binarycopy(inref=%scan(&appendrefs,&i), outref=&baseref, mode=APPEND)
%end;
%mend mp_appendfile;/**
@file @file
@brief Generic assertion @brief Generic assertion
@details Useful in the context of writing sasjs tests. The results of the @details Useful in the context of writing sasjs tests. The results of the
@@ -2131,6 +2188,7 @@ Usage:
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_existds.sas @li mf_existds.sas
@li mf_getuniquename.sas
@li mf_nobs.sas @li mf_nobs.sas
@li mp_abort.sas @li mp_abort.sas
@@ -2216,6 +2274,26 @@ Usage:
select count(*) into: orig from &lib..&ds; select count(*) into: orig from &lib..&ds;
quit; quit;
%local notfound tmp1 tmp2;
%let tmp1=%mf_getuniquename();
%let tmp2=%mf_getuniquename();
/* this is a bit convoluted - but using sql outobs=10 throws warnings */
proc sql noprint;
create view &tmp1 as
select distinct &col
from &lib..&ds
where &col not in (
select &ccol from &clib..&cds
);
data &tmp2;
set &tmp1;
if _n_>10 then stop;
run;
proc sql;
select distinct &col into: notfound separated by ' ' from &tmp2;
%mp_abort(iftrue= (&syscc ne 0) %mp_abort(iftrue= (&syscc ne 0)
,mac=&sysmacroname ,mac=&sysmacroname
,msg=%str(syscc=&syscc after macro query) ,msg=%str(syscc=&syscc after macro query)
@@ -2226,7 +2304,7 @@ Usage:
test_description=symget('desc'); test_description=symget('desc');
test_result='FAIL'; test_result='FAIL';
test_comments="&sysmacroname: &lib..&ds..&col has &result values " test_comments="&sysmacroname: &lib..&ds..&col has &result values "
!!"not in &clib..&cds..&ccol "; !!"not in &clib..&cds..&ccol.. First 10 vals:"!!symget('notfound');
%if &test=ANYVAL %then %do; %if &test=ANYVAL %then %do;
if &result < &orig then test_result='PASS'; if &result < &orig then test_result='PASS';
%end; %end;
@@ -3293,8 +3371,8 @@ run;
%let nvars=0; %let nvars=0;
proc sql noprint; proc sql noprint;
select count(*) into: nvars from dictionary.columns select count(*) into: nvars from dictionary.columns
where libname="%scan(%upcase(&base_ds),1)" where upcase(libname)="%scan(%upcase(&base_ds),1)"
and memname="%scan(%upcase(&base_ds),2)"; and upcase(memname)="%scan(%upcase(&base_ds),2)";
%if &nvars=0 %then %do; %if &nvars=0 %then %do;
%put %str(WARN)ING: Dataset &base_ds has no variables, will not be converted.; %put %str(WARN)ING: Dataset &base_ds has no variables, will not be converted.;
%return; %return;
@@ -3350,8 +3428,8 @@ proc sql
reset outobs=max; reset outobs=max;
create table datalines1 as create table datalines1 as
select name,type,length,varnum,format,label from dictionary.columns select name,type,length,varnum,format,label from dictionary.columns
where libname="%upcase(%scan(&base_ds,1))" where upcase(libname)="%upcase(%scan(&base_ds,1))"
and memname="%upcase(%scan(&base_ds,2))"; and upcase(memname)="%upcase(%scan(&base_ds,2))";
/** /**
Due to long decimals cannot use best. format Due to long decimals cannot use best. format
@@ -4230,6 +4308,70 @@ filename &fref1 clear;
%mend mp_filtervalidate; %mend mp_filtervalidate;
/** /**
@file
@brief Creates a dataset with column metadata.
@details This macro takes the `proc contents` output and "tidies it up" in the
following ways:
@li Blank labels are filled in with column names
@li Formats are reconstructed with default values
@li Types such as DATE / TIME / DATETIME are inferred from the formats
Example usage:
%mp_getcols(sashelp.airline,outds=work.myds)
@param ds The dataset from which to obtain column metadata
@param outds= (work.cols) The output dataset to create. Sample data:
|NAME $|LENGTH 8|VARNUM 8|LABEL $|FORMAT $49|TYPE $1 |DDTYPE $|
|---|---|---|---|---|---|---|
|AIR|8|2|international airline travel (thousands)|8.|N|NUMERIC|
|DATE|8|1|DATE|MONYY.|N|DATE|
|REGION|3|3|REGION|$3.|C|CHARACTER|
<h4> Related Macros </h4>
@li mf_getvarlist.sas
@li mm_getcols.sas
@version 9.2
@author Allan Bowe
**/
%macro mp_getcols(ds, outds=work.cols);
proc contents noprint data=&ds
out=_data_ (keep=name type length label varnum format:);
run;
data &outds(keep=name type length varnum format label ddtype);
set &syslast(rename=(format=format2 type=type2));
name=upcase(name);
if type2=2 then do;
length format $49.;
if format2='' then format=cats('$',length,'.');
else if formatl=0 then format=cats(format2,'.');
else format=cats(format2,formatl,'.');
type='C';
ddtype='CHARACTER';
end;
else do;
if format2='' then format=cats(length,'.');
else if formatl=0 then format=cats(format2,'.');
else if formatd=0 then format=cats(format2,formatl,'.');
else format=cats(format2,formatl,'.',formatd);
type='N';
if format=:'DATETIME' then ddtype='DATETIME';
else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY'
or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA'
or format=:'MONYY'
then ddtype='DATE';
else if format=:'TIME' then ddtype='TIME';
else ddtype='NUMERIC';
end;
if label='' then label=name;
run;
%mend mp_getcols;/**
@file mp_getconstraints.sas @file mp_getconstraints.sas
@brief Get constraint details at column level @brief Get constraint details at column level
@details Useful for capturing constraints before they are dropped / reapplied @details Useful for capturing constraints before they are dropped / reapplied
@@ -4270,21 +4412,21 @@ filename &fref1 clear;
/* must use SQL as proc datasets does not support length changes */ /* must use SQL as proc datasets does not support length changes */
proc sql noprint; proc sql noprint;
create table &outds as create table &outds as
select a.TABLE_CATALOG as libref select upcase(a.TABLE_CATALOG) as libref
,a.TABLE_NAME ,upcase(a.TABLE_NAME) as TABLE_NAME
,a.constraint_type ,a.constraint_type
,a.constraint_name ,a.constraint_name
,b.column_name ,b.column_name
from dictionary.TABLE_CONSTRAINTS a from dictionary.TABLE_CONSTRAINTS a
left join dictionary.constraint_column_usage b left join dictionary.constraint_column_usage b
on a.TABLE_CATALOG=b.TABLE_CATALOG on upcase(a.TABLE_CATALOG)=upcase(b.TABLE_CATALOG)
and a.TABLE_NAME=b.TABLE_NAME and upcase(a.TABLE_NAME)=upcase(b.TABLE_NAME)
and a.constraint_name=b.constraint_name and a.constraint_name=b.constraint_name
where a.TABLE_CATALOG="&lib" where upcase(a.TABLE_CATALOG)="&lib"
and b.TABLE_CATALOG="&lib" and upcase(b.TABLE_CATALOG)="&lib"
%if "&ds" ne "" %then %do; %if "&ds" ne "" %then %do;
and a.TABLE_NAME="&ds" and upcase(a.TABLE_NAME)="&ds"
and b.TABLE_NAME="&ds" and upcase(b.TABLE_NAME)="&ds"
%end; %end;
; ;
@@ -4835,7 +4977,7 @@ run;
proc sql noprint; proc sql noprint;
select sysvalue into: schemaactual select sysvalue into: schemaactual
from dictionary.libnames from dictionary.libnames
where libname="&libref" and engine='SQLSVR'; where upcase(libname)="&libref" and engine='SQLSVR';
%let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref)); %let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref));
%do x=1 %to %sysfunc(countw(&dsnlist)); %do x=1 %to %sysfunc(countw(&dsnlist));
@@ -4928,7 +5070,7 @@ run;
proc sql noprint; proc sql noprint;
select sysvalue into: schemaactual select sysvalue into: schemaactual
from dictionary.libnames from dictionary.libnames
where libname="&libref" and engine='POSTGRES'; where upcase(libname)="&libref" and engine='POSTGRES';
%let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref)); %let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref));
data _null_; data _null_;
file &fref mod; file &fref mod;
@@ -6030,14 +6172,14 @@ select distinct lowcase(memname)
We take the standard definition one step further by embedding the informat We take the standard definition one step further by embedding the informat
in the table header row, like so: in the table header row, like so:
|var1:$|var2:best.|var3:date9.| |var1:$32|var2:best.|var3:date9.|
|---|---|---| |---|---|---|
|some text|42|01JAN1960| |some text|42|01JAN1960|
|blah|1|31DEC1999| |blah|1|31DEC1999|
Which resolves to: Which resolves to:
|var1:$|var2:best.|var3:date9.| |var1:$32|var2:best.|var3:date9.|
|---|---|---| |---|---|---|
|some text|42|01JAN1960| |some text|42|01JAN1960|
|blah|1|31DEC1999| |blah|1|31DEC1999|
@@ -9986,6 +10128,7 @@ data _null_;
put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; '; put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; ';
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; '; put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; '; put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
put ' put ",""SYSSITE"" : ""&syssite"" "; '; put ' put ",""SYSSITE"" : ""&syssite"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';
@@ -13481,6 +13624,7 @@ run;
put ",""SYSERRORTEXT"" : ""&syserrortext"" "; put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSJOBID"" : ""&sysjobid"" "; put ",""SYSJOBID"" : ""&sysjobid"" ";
put ",""SYSSCPL"" : ""&sysscpl"" ";
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
@@ -14952,6 +15096,7 @@ data _null_;
put ' put ",""SYSCC"" : ""&syscc"" "; '; put ' put ",""SYSCC"" : ""&syscc"" "; ';
put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; '; put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; ';
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; '; put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
put ' put ",""SYSSITE"" : ""&syssite"" "; '; put ' put ",""SYSSITE"" : ""&syssite"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';
@@ -18791,6 +18936,7 @@ filename &fref1 clear;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
put ",""SYSERRORTEXT"" : ""&syserrortext"" "; put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSSCPL"" : ""&sysscpl"" ";
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;

View File

@@ -193,6 +193,7 @@
put ",""SYSERRORTEXT"" : " syserrortext; put ",""SYSERRORTEXT"" : " syserrortext;
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSJOBID"" : ""&sysjobid"" "; put ",""SYSJOBID"" : ""&sysjobid"" ";
put ",""SYSSCPL"" : ""&sysscpl"" ";
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
@@ -207,7 +208,7 @@
%if "&sysprocessmode " = "SAS Stored Process Server " %then %do; %if "&sysprocessmode " = "SAS Stored Process Server " %then %do;
data _null_; data _null_;
putlog 'stpsrvset program error and syscc'; putlog 'stpsrvset program err and syscc';
rc=stpsrvset('program error', 0); rc=stpsrvset('program error', 0);
call symputx("syscc",0,"g"); call symputx("syscc",0,"g");
run; run;

57
base/mp_appendfile.sas Normal file
View File

@@ -0,0 +1,57 @@
/**
@file
@brief Append (concatenate) two or more files.
@details Will append one more more `appendrefs` (filerefs) to a `baseref`.
Uses a binary mechanism, so will work with any file type. For that reason -
use with care! And supply your own trailing carriage returns in each file..
Usage:
filename tmp1 temp;
filename tmp2 temp;
filename tmp3 temp;
data _null_; file tmp1; put 'base file';
data _null_; file tmp2; put 'append1';
data _null_; file tmp3; put 'append2';
run;
%mp_appendfile(baseref=tmp1, appendrefs=tmp2 tmp3)
@param [in] baseref= Fileref of the base file (should exist)
@param [in] appendrefs= One or more filerefs to be appended to the base
fileref. Space separated.
@version 9.2
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mp_binarycopy.sas
**/
%macro mp_appendfile(
baseref=0,
appendrefs=0
)/*/STORE SOURCE*/;
%mp_abort(iftrue= (&baseref=0)
,mac=&sysmacroname
,msg=%str(Baseref NOT specified!)
)
%mp_abort(iftrue= (&appendrefs=0)
,mac=&sysmacroname
,msg=%str(Appendrefs NOT specified!)
)
%local i;
%do i=1 %to %sysfunc(countw(&appendrefs));
%mp_abort(iftrue= (&syscc>0)
,mac=&sysmacroname
,msg=%str(syscc=&syscc)
)
%mp_binarycopy(inref=%scan(&appendrefs,&i), outref=&baseref, mode=APPEND)
%end;
%mend mp_appendfile;

View File

@@ -30,6 +30,7 @@
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_existds.sas @li mf_existds.sas
@li mf_getuniquename.sas
@li mf_nobs.sas @li mf_nobs.sas
@li mp_abort.sas @li mp_abort.sas
@@ -115,6 +116,26 @@
select count(*) into: orig from &lib..&ds; select count(*) into: orig from &lib..&ds;
quit; quit;
%local notfound tmp1 tmp2;
%let tmp1=%mf_getuniquename();
%let tmp2=%mf_getuniquename();
/* this is a bit convoluted - but using sql outobs=10 throws warnings */
proc sql noprint;
create view &tmp1 as
select distinct &col
from &lib..&ds
where &col not in (
select &ccol from &clib..&cds
);
data &tmp2;
set &tmp1;
if _n_>10 then stop;
run;
proc sql;
select distinct &col into: notfound separated by ' ' from &tmp2;
%mp_abort(iftrue= (&syscc ne 0) %mp_abort(iftrue= (&syscc ne 0)
,mac=&sysmacroname ,mac=&sysmacroname
,msg=%str(syscc=&syscc after macro query) ,msg=%str(syscc=&syscc after macro query)
@@ -125,7 +146,7 @@
test_description=symget('desc'); test_description=symget('desc');
test_result='FAIL'; test_result='FAIL';
test_comments="&sysmacroname: &lib..&ds..&col has &result values " test_comments="&sysmacroname: &lib..&ds..&col has &result values "
!!"not in &clib..&cds..&ccol "; !!"not in &clib..&cds..&ccol.. First 10 vals:"!!symget('notfound');
%if &test=ANYVAL %then %do; %if &test=ANYVAL %then %do;
if &result < &orig then test_result='PASS'; if &result < &orig then test_result='PASS';
%end; %end;

View File

@@ -58,8 +58,8 @@
%let nvars=0; %let nvars=0;
proc sql noprint; proc sql noprint;
select count(*) into: nvars from dictionary.columns select count(*) into: nvars from dictionary.columns
where libname="%scan(%upcase(&base_ds),1)" where upcase(libname)="%scan(%upcase(&base_ds),1)"
and memname="%scan(%upcase(&base_ds),2)"; and upcase(memname)="%scan(%upcase(&base_ds),2)";
%if &nvars=0 %then %do; %if &nvars=0 %then %do;
%put %str(WARN)ING: Dataset &base_ds has no variables, will not be converted.; %put %str(WARN)ING: Dataset &base_ds has no variables, will not be converted.;
%return; %return;
@@ -115,8 +115,8 @@ proc sql
reset outobs=max; reset outobs=max;
create table datalines1 as create table datalines1 as
select name,type,length,varnum,format,label from dictionary.columns select name,type,length,varnum,format,label from dictionary.columns
where libname="%upcase(%scan(&base_ds,1))" where upcase(libname)="%upcase(%scan(&base_ds,1))"
and memname="%upcase(%scan(&base_ds,2))"; and upcase(memname)="%upcase(%scan(&base_ds,2))";
/** /**
Due to long decimals cannot use best. format Due to long decimals cannot use best. format

65
base/mp_getcols.sas Normal file
View File

@@ -0,0 +1,65 @@
/**
@file
@brief Creates a dataset with column metadata.
@details This macro takes the `proc contents` output and "tidies it up" in the
following ways:
@li Blank labels are filled in with column names
@li Formats are reconstructed with default values
@li Types such as DATE / TIME / DATETIME are inferred from the formats
Example usage:
%mp_getcols(sashelp.airline,outds=work.myds)
@param ds The dataset from which to obtain column metadata
@param outds= (work.cols) The output dataset to create. Sample data:
|NAME $|LENGTH 8|VARNUM 8|LABEL $|FORMAT $49|TYPE $1 |DDTYPE $|
|---|---|---|---|---|---|---|
|AIR|8|2|international airline travel (thousands)|8.|N|NUMERIC|
|DATE|8|1|DATE|MONYY.|N|DATE|
|REGION|3|3|REGION|$3.|C|CHARACTER|
<h4> Related Macros </h4>
@li mf_getvarlist.sas
@li mm_getcols.sas
@version 9.2
@author Allan Bowe
**/
%macro mp_getcols(ds, outds=work.cols);
proc contents noprint data=&ds
out=_data_ (keep=name type length label varnum format:);
run;
data &outds(keep=name type length varnum format label ddtype);
set &syslast(rename=(format=format2 type=type2));
name=upcase(name);
if type2=2 then do;
length format $49.;
if format2='' then format=cats('$',length,'.');
else if formatl=0 then format=cats(format2,'.');
else format=cats(format2,formatl,'.');
type='C';
ddtype='CHARACTER';
end;
else do;
if format2='' then format=cats(length,'.');
else if formatl=0 then format=cats(format2,'.');
else if formatd=0 then format=cats(format2,formatl,'.');
else format=cats(format2,formatl,'.',formatd);
type='N';
if format=:'DATETIME' then ddtype='DATETIME';
else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY'
or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA'
or format=:'MONYY'
then ddtype='DATE';
else if format=:'TIME' then ddtype='TIME';
else ddtype='NUMERIC';
end;
if label='' then label=name;
run;
%mend mp_getcols;

View File

@@ -39,21 +39,21 @@
/* must use SQL as proc datasets does not support length changes */ /* must use SQL as proc datasets does not support length changes */
proc sql noprint; proc sql noprint;
create table &outds as create table &outds as
select a.TABLE_CATALOG as libref select upcase(a.TABLE_CATALOG) as libref
,a.TABLE_NAME ,upcase(a.TABLE_NAME) as TABLE_NAME
,a.constraint_type ,a.constraint_type
,a.constraint_name ,a.constraint_name
,b.column_name ,b.column_name
from dictionary.TABLE_CONSTRAINTS a from dictionary.TABLE_CONSTRAINTS a
left join dictionary.constraint_column_usage b left join dictionary.constraint_column_usage b
on a.TABLE_CATALOG=b.TABLE_CATALOG on upcase(a.TABLE_CATALOG)=upcase(b.TABLE_CATALOG)
and a.TABLE_NAME=b.TABLE_NAME and upcase(a.TABLE_NAME)=upcase(b.TABLE_NAME)
and a.constraint_name=b.constraint_name and a.constraint_name=b.constraint_name
where a.TABLE_CATALOG="&lib" where upcase(a.TABLE_CATALOG)="&lib"
and b.TABLE_CATALOG="&lib" and upcase(b.TABLE_CATALOG)="&lib"
%if "&ds" ne "" %then %do; %if "&ds" ne "" %then %do;
and a.TABLE_NAME="&ds" and upcase(a.TABLE_NAME)="&ds"
and b.TABLE_NAME="&ds" and upcase(b.TABLE_NAME)="&ds"
%end; %end;
; ;

View File

@@ -211,7 +211,7 @@ run;
proc sql noprint; proc sql noprint;
select sysvalue into: schemaactual select sysvalue into: schemaactual
from dictionary.libnames from dictionary.libnames
where libname="&libref" and engine='SQLSVR'; where upcase(libname)="&libref" and engine='SQLSVR';
%let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref)); %let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref));
%do x=1 %to %sysfunc(countw(&dsnlist)); %do x=1 %to %sysfunc(countw(&dsnlist));
@@ -304,7 +304,7 @@ run;
proc sql noprint; proc sql noprint;
select sysvalue into: schemaactual select sysvalue into: schemaactual
from dictionary.libnames from dictionary.libnames
where libname="&libref" and engine='POSTGRES'; where upcase(libname)="&libref" and engine='POSTGRES';
%let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref)); %let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref));
data _null_; data _null_;
file &fref mod; file &fref mod;

View File

@@ -14,14 +14,14 @@
We take the standard definition one step further by embedding the informat We take the standard definition one step further by embedding the informat
in the table header row, like so: in the table header row, like so:
|var1:$|var2:best.|var3:date9.| |var1:$32|var2:best.|var3:date9.|
|---|---|---| |---|---|---|
|some text|42|01JAN1960| |some text|42|01JAN1960|
|blah|1|31DEC1999| |blah|1|31DEC1999|
Which resolves to: Which resolves to:
|var1:$|var2:best.|var3:date9.| |var1:$32|var2:best.|var3:date9.|
|---|---|---| |---|---|---|
|some text|42|01JAN1960| |some text|42|01JAN1960|
|blah|1|31DEC1999| |blah|1|31DEC1999|

View File

@@ -385,6 +385,7 @@ data _null_;
put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; '; put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; ';
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; '; put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; '; put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
put ' put ",""SYSSITE"" : ""&syssite"" "; '; put ' put ",""SYSSITE"" : ""&syssite"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';

View File

@@ -155,6 +155,7 @@
put ",""SYSERRORTEXT"" : ""&syserrortext"" "; put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSJOBID"" : ""&sysjobid"" "; put ",""SYSJOBID"" : ""&sysjobid"" ";
put ",""SYSSCPL"" : ""&sysscpl"" ";
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;

View File

@@ -0,0 +1,41 @@
/**
@file
@brief Testing mp_appendfile.sas macro
<h4> SAS Macros </h4>
@li mp_appendfile.sas
@li mp_assert.sas
**/
filename tmp1 temp;
filename tmp2 temp;
filename tmp3 temp;
data _null_; file tmp1; put 'base file';
data _null_; file tmp2; put 'append1';
data _null_; file tmp3; put 'append2';
run;
%mp_appendfile(baseref=tmp1, appendrefs=tmp2 tmp3)
data _null_;
infile tmp1;
input;
put _infile_;
call symputx(cats('check',_n_),_infile_);
run;
%global check1 check2 check3;
%mp_assert(
iftrue=("&check1"="base file"),
desc=Line 1 of file tmp1 is correct,
outds=work.test_results
)
%mp_assert(
iftrue=("&check2"="append1"),
desc=Line 2 of file tmp1 is correct,
outds=work.test_results
)
%mp_assert(
iftrue=("&check3"="append2"),
desc=Line 3 of file tmp1 is correct,
outds=work.test_results
)

View File

@@ -0,0 +1,33 @@
/**
@file
@brief Testing mp_getcols macro
<h4> SAS Macros </h4>
@li mp_getcols.sas
@li mp_assertcolvals.sas
@li mp_assertdsobs.sas
**/
/* valid filter */
%mp_getcols(sashelp.airline,outds=work.info)
%mp_assertdsobs(work.info,
desc=Has 3 records,
test=EQUALS 3,
outds=work.test_results
)
data work.check;
length val $10;
do val='NUMERIC','DATE','CHARACTER';
output;
end;
run;
%mp_assertcolvals(work.info.ddtype,
checkvals=work.check.val,
desc=All values have a match,
test=ALLVALS
)

View File

@@ -590,6 +590,7 @@ data _null_;
put ' put ",""SYSCC"" : ""&syscc"" "; '; put ' put ",""SYSCC"" : ""&syscc"" "; ';
put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; '; put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; ';
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; '; put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
put ' put ",""SYSSITE"" : ""&syssite"" "; '; put ' put ",""SYSSITE"" : ""&syssite"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';

View File

@@ -215,6 +215,7 @@
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
put ",""SYSERRORTEXT"" : ""&syserrortext"" "; put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSSCPL"" : ""&sysscpl"" ";
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;