SQLinDS, source files updated

SQLinDS, source files updated
This commit is contained in:
yabwon
2020-10-14 16:33:07 +02:00
parent bfdcd238ec
commit 02f71de424
7 changed files with 102 additions and 169 deletions

View File

@@ -1,19 +1,21 @@
/*** HELP START ***/ /*** HELP START ***/
/*
## >>> library `dsSQL`: <<< <a name="library-dssql"></a> ########################
/* >>> dsSQL library: <<< The `dsSQL` library stores temporary views
* generated during the `%SQL()` macro execution.
* The dsSQL library stores temporary views
* generated during the %SQL() macro execution.
* If possible a subdirectory of WORK is created as:
LIBNAME dsSQL BASE "%sysfunc(pathname(WORK))/dsSQLtmp"; If possible a subdirectory of the `WORK` location is created, like:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
* if not possible then redirects to WORK as: LIBNAME dsSQL BASE "%sysfunc(pathname(WORK))/dsSQLtmp";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LIBNAME dsSQL BASE "%sysfunc(pathname(WORK))";
**/
if not possible, then redirects to the `WORK` location, like:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
LIBNAME dsSQL BASE "%sysfunc(pathname(WORK))";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
*/
/*** HELP END ***/ /*** HELP END ***/
data _null_; data _null_;
@@ -25,5 +27,5 @@ data _null_;
rc1 = LIBNAME("dsSQL", "%sysfunc(pathname(work))", "BASE"); rc1 = LIBNAME("dsSQL", "%sysfunc(pathname(work))", "BASE");
run; run;
/* list details about the library in the log */ /* list the details about the library in the log */
libname dsSQL LIST; libname dsSQL LIST;

View File

@@ -1,19 +1,15 @@
/*** HELP START ***/ /*** HELP START ***/
/*
## >>> `%dsSQL_Inner()` macro: <<< <a name="dssql-inner-macro"></a> #############
/* >>> %dsSQL_Inner() macro: <<< **Internal** macro called by `dsSQL()` function.
* The macro generates a uniquely named SQL view on the fly
* Internal macro called by dsSQL() function. which is then stored in the `dsSQL` library.
* The macro generates a uniqualy named sql view on the fly
* which is stored in DSSQL library. Recommended for *SAS 9.3* and higher.
*
* Recommended for SAS 9.3 and higher.
* Based on paper:
* "Use the Full Power of SAS in Your Function-Style Macros"
* by Mike Rhoads, Westat, Rockville, MD
* https://support.sas.com/resources/papers/proceedings12/004-2012.pdf
*
**/
---
*/
/*** HELP END ***/ /*** HELP END ***/
/* inner macro */ /* inner macro */
@@ -57,7 +53,7 @@
%put *****************; %put *****************;
proc sql; proc sql;
%include &tempfile2.; /* &query */ %include &tempfile2.; /* the &query */
; ;
quit; quit;
filename &tempfile1. clear; filename &tempfile1. clear;

View File

@@ -1,41 +1,47 @@
/*** HELP START ***/ /*** HELP START ***/
/*
## >>> `%SQL()` macro: <<< <a name="dssql-macro"></a> ###########################
/* >>> %SQL() macro: <<< The **main** macro which allows to use
* SQL queries in the data step.
* Main macro which allows to use
* SQL's queries in the data step. Recommended for *SAS 9.3* and higher.
* Recommended for SAS 9.3 and higher.
* Based on paper: Based on the article *"Use the Full Power of SAS in Your Function-Style Macros"*
* "Use the Full Power of SAS in Your Function-Style Macros" by *Mike Rhoads* (Westat, Rockville), available at:
* by Mike Rhoads, Westat, Rockville, MD [https://support.sas.com/resources/papers/proceedings12/004-2012.pdf](https://support.sas.com/resources/papers/proceedings12/004-2012.pdf)
* https://support.sas.com/resources/papers/proceedings12/004-2012.pdf
*
* SYNTAX:
%sql(<nonempty sql querry code>) ### SYNTAX: ###################################################################
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%sql(<nonempty sql querry code>)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* The sql querry code is limited to 32000 bytes. The sql query code is limited to *32000* bytes.
*
* EXAMPLE 1: simple sql query
data class_subset; ### EXAMPLES: #################################################################
set %SQL(select name, sex, height from sashelp.class where age > 12);
run;
* EXAMPLE 2: query with dataset options **EXAMPLE 1**: simple SQL query
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data class_subset;
set %SQL(select name, sex, height from sashelp.class where age > 12);
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
data renamed; **EXAMPLE 2**: query with dataset options
set %SQL(select * from sashelp.class where sex = "F")(rename = (age=age2)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
run; data renamed;
set %SQL(select * from sashelp.class where sex = "F")(rename = (age=age2));
* EXAMPLE 3: dictionaries in datastep run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
data dictionary;
set %SQL(select * from dictionary.macros);
run;
**/
**EXAMPLE 3**: dictionaries in the data step
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data dictionary;
set %SQL(select * from dictionary.macros);
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
*/
/*** HELP END ***/ /*** HELP END ***/

View File

@@ -1,19 +1,26 @@
/*** HELP START ***/ /*** HELP START ***/
/*
## >>> `dsSQL()` function: <<< <a name="dssql-function"></a> ####################
/* >>> dsSQL() function: <<< **Internal** function called by the `%SQL()` macro.
* The function pass a query code from the `%SQL()`
* Internal function called by %SQL() macro. macro to the `%dsSQL_Inner()` internal macro.
* The function pass query code from the %SQL()
* macro to the %dsSQL_Inner() innternal macreo.
*
* Recommended for SAS 9.3 and higher.
* Based on paper:
* "Use the Full Power of SAS in Your Function-Style Macros"
* by Mike Rhoads, Westat, Rockville, MD
* https://support.sas.com/resources/papers/proceedings12/004-2012.pdf
*
**/
Recommended for *SAS 9.3* and higher.
### SYNTAX: ###################################################################
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
dsSQL(unique_index_2, query)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Arguments description**:
1. `unique_index_2` - *Numeric*, internal variable, a unique index for views.
2. `query` - *Character*, internal variable, contains query text.
---
*/
/*** HELP END ***/ /*** HELP END ***/
proc fcmp proc fcmp

View File

@@ -6,7 +6,7 @@
Type: Package :/*required, not null, constant value*/ Type: Package :/*required, not null, constant value*/
Package: SQLinDS :/*required, not null, up to 24 characters, naming restrictions like for a dataset name! */ Package: SQLinDS :/*required, not null, up to 24 characters, naming restrictions like for a dataset name! */
Title: SQL queries in Data Step :/*required, not null*/ Title: SQL queries in Data Step :/*required, not null*/
Version: 2.1 :/*required, not null*/ Version: 2.2 :/*required, not null*/
Author: Mike Rhoads (RhoadsM1@Westat.com) :/*required, not null*/ Author: Mike Rhoads (RhoadsM1@Westat.com) :/*required, not null*/
Maintainer: Bartosz Jablonski (yabwon@gmail.com) :/*required, not null*/ Maintainer: Bartosz Jablonski (yabwon@gmail.com) :/*required, not null*/
License: MIT :/*required, not null, values: MIT, GPL2, BSD, etc.*/ License: MIT :/*required, not null, values: MIT, GPL2, BSD, etc.*/
@@ -18,28 +18,32 @@ Required: "Base SAS Software" :/*optional, COMMA separated, Q
/* All the text below will be used in help */ /* All the text below will be used in help */
DESCRIPTION START: DESCRIPTION START:
The SQLinDS package is an implementation of # The SQLinDS package [ver. 2.2] <a name="sqlinds-package"></a> ###############################################
the macro-function-sandwich concept introduced in:
"Use the Full Power of SAS in Your Function-Style Macros" The **SQLinDS** package is an implementation of
the article by Mike Rhoads, Westat, Rockville, MD the *macro-function-sandwich* concept introduced in the
*"Use the Full Power of SAS in Your Function-Style Macros"*,
the article by *Mike Rhoads (Westat, Rockville)*.
Copy of the article is available at: Copy of the article is available at:
https://support.sas.com/resources/papers/proceedings12/004-2012.pdf [https://support.sas.com/resources/papers/proceedings12/004-2012.pdf](https://support.sas.com/resources/papers/proceedings12/004-2012.pdf)
Package provides ability to "execute" SQL queries inside a datastep, e.g.
Package provides ability to *execute* SQL queries inside a data step, e.g.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data class; data class;
set %SQL(select * from sashelp.class); set %SQL(select * from sashelp.class);
run; run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See the help for the `%SQL()` macro to find more examples.
### Content ###################################################################
SQLinDS package contains the following components: SQLinDS package contains the following components:
1) %SQL() macro - the main package macro available for the User 1. `%SQL()` macro - the main package macro available for the User
2. `dsSQL()` function (internal)
2) dsSQL() function (internal) 3. `%dsSQL_inner()` macro (internal)
3) %dsSQL_inner() macro (internal) 4. Library `DSSQL` (created as a subdirectory of the `WORK` library)
4) Library DSSQL (created in a subdirectory of the WORK library)
See help for the %SQL() macro to find more examples.
---
DESCRIPTION END: DESCRIPTION END:

View File

@@ -1,6 +1,6 @@
resetline;
filename packages "C:\SAS_PACKAGES\SPF";
filename packages "C:\SAS_PACKAGES\SASPackagesFramework";
%include packages(SPFinit.sas); %include packages(SPFinit.sas);
ods html; ods html;

View File

@@ -1,82 +0,0 @@
options dlCreateDir;
libname dsSQL "%sysfunc(pathname(work))/dsSQLtmp";
/* makro zewnetrzne */
%MACRO SQL() / PARMBUFF SECURE;
%let SYSPBUFF = %superq(SYSPBUFF); /* maskujemy znaki specjalne */
%let SYSPBUFF = %substr(&SYSPBUFF,2,%LENGTH(&SYSPBUFF) - 2); /* kasujemy otwierający i zamykający nawias */
%let SYSPBUFF = %superq(SYSPBUFF); /* maskujemy jeszcze raz */
%let SYSPBUFF = %sysfunc(quote(&SYSPBUFF)); /* dodajemy cudzyslowy */
%put ***the querry***;
%put &SYSPBUFF.;
%put ****************;
%local UNIQUE_INDEX; /* dodatkowa zmienna indeksujaca, zeby tworzony widok byl unikalny */
%let UNIQUE_INDEX = &SYSINDEX; /* przypisujemy jej wartosc */
%sysfunc(dsSQL(&UNIQUE_INDEX, &SYSPBUFF)) /* <-- wywolulemy funkcje dsSQL */
%MEND SQL;
/* funkcja */
%macro MacroFunctionSandwich_functions();
%local _cmplib_;
options APPEND=(cmplib = WORK.DATASTEPSQLFUNCTIONS) ;
%let _cmplib_ = %sysfunc(getoption(cmplib));
%put NOTE:[&sysmacroname.] *&=_cmplib_*;
options cmplib = _null_;
proc fcmp outlib=work.datastepSQLfunctions.package;
function dsSQL(unique_index_2, query $) $ 41;
length query query_arg $ 32000 viewname $ 41; /* query_arg mozna zmienic na dluzszy, np. 32000 :-) */
query_arg = dequote(query);
rc = run_macro('dsSQL_Inner', unique_index_2, query_arg, viewname); /* <-- wywolulemy makro wewnetrzne dsSQL_Inner */
if rc = 0 then return(trim(viewname));
else do;
return(" ");
put 'ERROR:[function dsSQL] A problem with the function';
end;
endsub;
run;
options cmplib = &_cmplib_.;
%let _cmplib_ = %sysfunc(getoption(cmplib));
%put NOTE:[&sysmacroname.] *&=_cmplib_*;
%mend MacroFunctionSandwich_functions;
%MacroFunctionSandwich_functions()
/* delete macro MacroFunctionSandwich_functions since it is not needed */
proc sql;
create table _%sysfunc(datetime(), hex16.)_ as
select memname, objname
from dictionary.catalogs
where
objname = upcase('MACROFUNCTIONSANDWICH_FUNCTIONS')
and objtype = 'MACRO'
and libname = 'WORK'
order by memname, objname
;
quit;
data _null_;
set _last_;
call execute('proc catalog cat = work.' !! strip(memname) !! ' et = macro force;');
call execute('delete ' !! strip(objname) !! '; run;');
call execute('quit;');
run;
proc delete data = _last_;
run;
/* makro wewnetrzne */
%MACRO dsSQL_Inner() / SECURE;
%local query;
%let query = %superq(query_arg);
%let query = %sysfunc(dequote(&query));
%let viewname = dsSQL.dsSQLtmpview&UNIQUE_INDEX_2;
proc sql;
create view &viewname as &query;
quit;
%MEND dsSQL_Inner;