mirror of
https://github.com/yabwon/SAS_PACKAGES.git
synced 2026-01-15 18:40:06 +00:00
SQLinDS, source files updated
SQLinDS, source files updated
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 ***/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
|
||||||
Reference in New Issue
Block a user