mirror of
https://github.com/sasjs/core.git
synced 2026-01-02 07:10:06 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58784b2f28 | ||
|
|
e125aace9b | ||
|
|
b02a9e3478 | ||
|
|
3d3c76c836 | ||
|
|
e039f1cd83 | ||
|
|
6c8165601d | ||
|
|
596624c1bf | ||
|
|
4aca34d4c2 |
@@ -1,2 +1,11 @@
|
||||
#!/bin/sh
|
||||
sasjs lint
|
||||
sasjs lint
|
||||
|
||||
# Avoid commits to the master branch
|
||||
BRANCH=`git rev-parse --abbrev-ref HEAD`
|
||||
|
||||
if [[ "$BRANCH" =~ ^(master|main|develop)$ ]]; then
|
||||
echo "You are on branch $BRANCH. Are you sure you want to commit to this branch?"
|
||||
echo "If so, commit with -n to bypass the pre-commit hook."
|
||||
exit 1
|
||||
fi
|
||||
78
all.sas
78
all.sas
@@ -6169,6 +6169,7 @@ create table &outds as
|
||||
|
||||
@param [in] libds dataset to hash
|
||||
@param [in] salt= Provide a salt (could be, for instance, the dataset name)
|
||||
@param [in] iftrue= A condition under which the macro should be executed.
|
||||
@param [out] outds= (work.mf_hashdataset) The output dataset to create. This
|
||||
will contain one column (hashkey) with one observation (a hex32.
|
||||
representation of the input hash)
|
||||
@@ -6183,10 +6184,14 @@ create table &outds as
|
||||
%macro mp_hashdataset(
|
||||
libds,
|
||||
outds=,
|
||||
salt=
|
||||
salt=,
|
||||
iftrue=%str(1=1)
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||
|
||||
%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
|
||||
%put %str(WARN)ING: Dataset &libds is empty;, or is not a dataset;
|
||||
%put %str(WARN)ING: Dataset &libds is empty, or is not a dataset;
|
||||
%end;
|
||||
%else %if %mf_getattrn(&libds,NLOBS)<0 %then %do;
|
||||
%put %str(ERR)OR: Dataset &libds is not a dataset;
|
||||
@@ -6367,15 +6372,15 @@ filename &tempref clear;
|
||||
compress=CHAR /* default is none so ensure we have something! */
|
||||
datastmtchk=ALLKEYWORDS /* protection from overwriting input datasets */
|
||||
errorcheck=STRICT /* catch errors in libname/filename statements */
|
||||
fmterr /* ensure error when a format cannot be found */
|
||||
mergenoby=ERROR /*
|
||||
fmterr /* ensure err when a format cannot be found */
|
||||
mergenoby=%str(ERR)OR /* Throw err when a merge has no BY variables */
|
||||
missing=. /* some sites change this which causes hard to detect errors */
|
||||
noquotelenmax /* avoid warnings for long strings */
|
||||
noreplace /* avoid overwriting permanent datasets */
|
||||
ps=max /* reduce log size slightly */
|
||||
validmemname=COMPATIBLE /* avoid special characters etc in table names */
|
||||
validvarname=V7 /* avoid special characters etc in variable names */
|
||||
varlenchk=ERROR /* fail hard if truncation (data loss) can result */
|
||||
varlenchk=%str(ERR)OR /* fail hard if truncation (data loss) can result */
|
||||
;
|
||||
|
||||
%mend mp_init;/**
|
||||
@@ -7737,22 +7742,28 @@ drop table &tempds;
|
||||
Usage:
|
||||
|
||||
%mp_searchdata(lib=sashelp, string=Jan)
|
||||
%mp_searchdata(lib=sashelp, numval=1)
|
||||
%mp_searchdata(lib=sashelp, ds=bird, numval=1)
|
||||
%mp_searchdata(lib=sashelp, ds=class, string=l,outobs=5)
|
||||
|
||||
|
||||
Outputs zero or more tables to an MPSEARCH library with specific records.
|
||||
|
||||
@param lib= the libref to search (should be already assigned)
|
||||
@param ds= the dataset to search (leave blank to search entire library)
|
||||
@param string= the string value to search
|
||||
@param numval= the numeric value to search (must be exact)
|
||||
@param outloc= the directory in which to create the output datasets with
|
||||
matching rows. Will default to a subfolder in the WORK library.
|
||||
@param outobs= set to a positive integer to restrict the number of
|
||||
@param [in] lib= The libref to search (should be already assigned)
|
||||
@param [in] ds= The dataset to search (leave blank to search entire library)
|
||||
@param [in] string= String value to search (case sensitive, can be partial)
|
||||
@param [in] numval= Numeric value to search (must be exact)
|
||||
@param [out] outloc= (0) Optionally specify the directory in which to
|
||||
create the the output datasets with matching rows. By default it will
|
||||
write them to a temporary subdirectory within the WORK folder.
|
||||
@param [out] outlib= (MPSEARCH) Assign a different libref to the output
|
||||
library containing the matching datasets / records
|
||||
@param [in] outobs= set to a positive integer to restrict the number of
|
||||
observations
|
||||
@param filter_text= add a (valid) filter clause to further filter the results
|
||||
@param [in] filter_text= (1=1) Add a (valid) filter clause to further filter
|
||||
the results.
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_getuniquename.sas
|
||||
@li mf_getvarlist.sas
|
||||
@li mf_getvartype.sas
|
||||
@li mf_mkdir.sas
|
||||
@@ -7762,11 +7773,12 @@ drop table &tempds;
|
||||
@author Allan Bowe
|
||||
**/
|
||||
|
||||
%macro mp_searchdata(lib=sashelp
|
||||
%macro mp_searchdata(lib=
|
||||
,ds=
|
||||
,string= /* the query will use a contains (?) operator */
|
||||
,numval= /* numeric must match exactly */
|
||||
,outloc=%sysfunc(pathname(work))/mpsearch
|
||||
,outloc=0
|
||||
,outlib=MPSEARCH
|
||||
,outobs=-1
|
||||
,filter_text=%str(1=1)
|
||||
)/*/STORE SOURCE*/;
|
||||
@@ -7783,8 +7795,12 @@ drop table &tempds;
|
||||
%if &string = %then %let type=N;
|
||||
%else %let type=C;
|
||||
|
||||
%if "&outloc"="0" %then %do;
|
||||
%let outloc=%sysfunc(pathname(work))/%mf_getuniquename();
|
||||
%end;
|
||||
|
||||
%mf_mkdir(&outloc)
|
||||
libname mpsearch "&outloc";
|
||||
libname &outlib "&outloc";
|
||||
|
||||
/* get the list of tables in the library */
|
||||
proc sql noprint;
|
||||
@@ -7796,11 +7812,6 @@ select distinct memname into: table_list separated by ' '
|
||||
%end;
|
||||
;
|
||||
/* check that we have something to check */
|
||||
proc sql
|
||||
%if &outobs>-1 %then %do;
|
||||
outobs=&outobs
|
||||
%end;
|
||||
;
|
||||
%if %length(&table_list)=0 %then %put library &lib contains no tables!;
|
||||
/* loop through each table */
|
||||
%else %do table_num=1 %to %sysfunc(countw(&table_list,%str( )));
|
||||
@@ -7811,10 +7822,10 @@ proc sql
|
||||
%end;
|
||||
%else %do;
|
||||
%let check_tm=%sysfunc(datetime());
|
||||
/* build sql statement */
|
||||
create table mpsearch.&table as select * from &lib..&table
|
||||
where %unquote(&filter_text) and
|
||||
(0
|
||||
/* prep input */
|
||||
data &outlib..&table;
|
||||
set &lib..&table;
|
||||
where %unquote(&filter_text) and ( 0
|
||||
/* loop through columns */
|
||||
%do colnum=1 %to %sysfunc(countw(&vars,%str( )));
|
||||
%let col=%scan(&vars,&colnum,%str( ));
|
||||
@@ -7828,15 +7839,20 @@ proc sql
|
||||
or ("&col"n = &numval)
|
||||
%end;
|
||||
%end;
|
||||
);
|
||||
);
|
||||
%if &outobs>-1 %then %do;
|
||||
if _n_ > &outobs then stop;
|
||||
%end;
|
||||
run;
|
||||
%put Search query for &table took
|
||||
%sysevalf(%sysfunc(datetime())-&check_tm) seconds;
|
||||
%if &sqlrc ne 0 %then %do;
|
||||
%put %str(WAR)NING: SQLRC=&sqlrc when processing &table;
|
||||
%if &syscc ne 0 %then %do;
|
||||
%put %str(ERR)ROR: SYSCC=&syscc when processing &lib..&table;
|
||||
%return;
|
||||
%end;
|
||||
%if %mf_nobs(mpsearch.&table)=0 %then %do;
|
||||
drop table mpsearch.&table;
|
||||
%if %mf_nobs(&outlib..&table)=0 %then %do;
|
||||
proc sql;
|
||||
drop table &outlib..&table;
|
||||
%end;
|
||||
%end;
|
||||
%end;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
@param [in] libds dataset to hash
|
||||
@param [in] salt= Provide a salt (could be, for instance, the dataset name)
|
||||
@param [in] iftrue= A condition under which the macro should be executed.
|
||||
@param [out] outds= (work.mf_hashdataset) The output dataset to create. This
|
||||
will contain one column (hashkey) with one observation (a hex32.
|
||||
representation of the input hash)
|
||||
@@ -35,10 +36,14 @@
|
||||
%macro mp_hashdataset(
|
||||
libds,
|
||||
outds=,
|
||||
salt=
|
||||
salt=,
|
||||
iftrue=%str(1=1)
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||
|
||||
%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
|
||||
%put %str(WARN)ING: Dataset &libds is empty;, or is not a dataset;
|
||||
%put %str(WARN)ING: Dataset &libds is empty, or is not a dataset;
|
||||
%end;
|
||||
%else %if %mf_getattrn(&libds,NLOBS)<0 %then %do;
|
||||
%put %str(ERR)OR: Dataset &libds is not a dataset;
|
||||
|
||||
@@ -40,15 +40,15 @@
|
||||
compress=CHAR /* default is none so ensure we have something! */
|
||||
datastmtchk=ALLKEYWORDS /* protection from overwriting input datasets */
|
||||
errorcheck=STRICT /* catch errors in libname/filename statements */
|
||||
fmterr /* ensure error when a format cannot be found */
|
||||
mergenoby=ERROR /*
|
||||
fmterr /* ensure err when a format cannot be found */
|
||||
mergenoby=%str(ERR)OR /* Throw err when a merge has no BY variables */
|
||||
missing=. /* some sites change this which causes hard to detect errors */
|
||||
noquotelenmax /* avoid warnings for long strings */
|
||||
noreplace /* avoid overwriting permanent datasets */
|
||||
ps=max /* reduce log size slightly */
|
||||
validmemname=COMPATIBLE /* avoid special characters etc in table names */
|
||||
validvarname=V7 /* avoid special characters etc in variable names */
|
||||
varlenchk=ERROR /* fail hard if truncation (data loss) can result */
|
||||
varlenchk=%str(ERR)OR /* fail hard if truncation (data loss) can result */
|
||||
;
|
||||
|
||||
%mend mp_init;
|
||||
@@ -11,22 +11,28 @@
|
||||
Usage:
|
||||
|
||||
%mp_searchdata(lib=sashelp, string=Jan)
|
||||
%mp_searchdata(lib=sashelp, numval=1)
|
||||
%mp_searchdata(lib=sashelp, ds=bird, numval=1)
|
||||
%mp_searchdata(lib=sashelp, ds=class, string=l,outobs=5)
|
||||
|
||||
|
||||
Outputs zero or more tables to an MPSEARCH library with specific records.
|
||||
|
||||
@param lib= the libref to search (should be already assigned)
|
||||
@param ds= the dataset to search (leave blank to search entire library)
|
||||
@param string= the string value to search
|
||||
@param numval= the numeric value to search (must be exact)
|
||||
@param outloc= the directory in which to create the output datasets with
|
||||
matching rows. Will default to a subfolder in the WORK library.
|
||||
@param outobs= set to a positive integer to restrict the number of
|
||||
@param [in] lib= The libref to search (should be already assigned)
|
||||
@param [in] ds= The dataset to search (leave blank to search entire library)
|
||||
@param [in] string= String value to search (case sensitive, can be partial)
|
||||
@param [in] numval= Numeric value to search (must be exact)
|
||||
@param [out] outloc= (0) Optionally specify the directory in which to
|
||||
create the the output datasets with matching rows. By default it will
|
||||
write them to a temporary subdirectory within the WORK folder.
|
||||
@param [out] outlib= (MPSEARCH) Assign a different libref to the output
|
||||
library containing the matching datasets / records
|
||||
@param [in] outobs= set to a positive integer to restrict the number of
|
||||
observations
|
||||
@param filter_text= add a (valid) filter clause to further filter the results
|
||||
@param [in] filter_text= (1=1) Add a (valid) filter clause to further filter
|
||||
the results.
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_getuniquename.sas
|
||||
@li mf_getvarlist.sas
|
||||
@li mf_getvartype.sas
|
||||
@li mf_mkdir.sas
|
||||
@@ -36,11 +42,12 @@
|
||||
@author Allan Bowe
|
||||
**/
|
||||
|
||||
%macro mp_searchdata(lib=sashelp
|
||||
%macro mp_searchdata(lib=
|
||||
,ds=
|
||||
,string= /* the query will use a contains (?) operator */
|
||||
,numval= /* numeric must match exactly */
|
||||
,outloc=%sysfunc(pathname(work))/mpsearch
|
||||
,outloc=0
|
||||
,outlib=MPSEARCH
|
||||
,outobs=-1
|
||||
,filter_text=%str(1=1)
|
||||
)/*/STORE SOURCE*/;
|
||||
@@ -57,8 +64,12 @@
|
||||
%if &string = %then %let type=N;
|
||||
%else %let type=C;
|
||||
|
||||
%if "&outloc"="0" %then %do;
|
||||
%let outloc=%sysfunc(pathname(work))/%mf_getuniquename();
|
||||
%end;
|
||||
|
||||
%mf_mkdir(&outloc)
|
||||
libname mpsearch "&outloc";
|
||||
libname &outlib "&outloc";
|
||||
|
||||
/* get the list of tables in the library */
|
||||
proc sql noprint;
|
||||
@@ -70,11 +81,6 @@ select distinct memname into: table_list separated by ' '
|
||||
%end;
|
||||
;
|
||||
/* check that we have something to check */
|
||||
proc sql
|
||||
%if &outobs>-1 %then %do;
|
||||
outobs=&outobs
|
||||
%end;
|
||||
;
|
||||
%if %length(&table_list)=0 %then %put library &lib contains no tables!;
|
||||
/* loop through each table */
|
||||
%else %do table_num=1 %to %sysfunc(countw(&table_list,%str( )));
|
||||
@@ -85,10 +91,10 @@ proc sql
|
||||
%end;
|
||||
%else %do;
|
||||
%let check_tm=%sysfunc(datetime());
|
||||
/* build sql statement */
|
||||
create table mpsearch.&table as select * from &lib..&table
|
||||
where %unquote(&filter_text) and
|
||||
(0
|
||||
/* prep input */
|
||||
data &outlib..&table;
|
||||
set &lib..&table;
|
||||
where %unquote(&filter_text) and ( 0
|
||||
/* loop through columns */
|
||||
%do colnum=1 %to %sysfunc(countw(&vars,%str( )));
|
||||
%let col=%scan(&vars,&colnum,%str( ));
|
||||
@@ -102,15 +108,20 @@ proc sql
|
||||
or ("&col"n = &numval)
|
||||
%end;
|
||||
%end;
|
||||
);
|
||||
);
|
||||
%if &outobs>-1 %then %do;
|
||||
if _n_ > &outobs then stop;
|
||||
%end;
|
||||
run;
|
||||
%put Search query for &table took
|
||||
%sysevalf(%sysfunc(datetime())-&check_tm) seconds;
|
||||
%if &sqlrc ne 0 %then %do;
|
||||
%put %str(WAR)NING: SQLRC=&sqlrc when processing &table;
|
||||
%if &syscc ne 0 %then %do;
|
||||
%put %str(ERR)ROR: SYSCC=&syscc when processing &lib..&table;
|
||||
%return;
|
||||
%end;
|
||||
%if %mf_nobs(mpsearch.&table)=0 %then %do;
|
||||
drop table mpsearch.&table;
|
||||
%if %mf_nobs(&outlib..&table)=0 %then %do;
|
||||
proc sql;
|
||||
drop table &outlib..&table;
|
||||
%end;
|
||||
%end;
|
||||
%end;
|
||||
|
||||
29
tests/crossplatform/mp_searchdata.test.sas
Normal file
29
tests/crossplatform/mp_searchdata.test.sas
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
@file
|
||||
@brief Testing mp_searchdata.sas
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mp_searchdata.sas
|
||||
@li mp_assert.sas
|
||||
|
||||
|
||||
**/
|
||||
|
||||
/** Test 1 - generic useage */
|
||||
|
||||
%mp_searchdata(lib=sashelp, ds=class, string=a)
|
||||
%mp_assert(
|
||||
iftrue=(&syscc=0),
|
||||
desc=No errors in regular usage,
|
||||
outds=work.test_results
|
||||
)
|
||||
|
||||
/** Test 2 - with obs issue */
|
||||
|
||||
%mp_searchdata(lib=sashelp, ds=class, string=l,outobs=5)
|
||||
|
||||
%mp_assert(
|
||||
iftrue=("&SYSWARNINGTEXT" = ""),
|
||||
desc=Ensuring WARN status is clean,
|
||||
outds=work.test_results
|
||||
)
|
||||
Reference in New Issue
Block a user