mirror of
https://github.com/yabwon/SAS_PACKAGES.git
synced 2026-01-14 18:10:06 +00:00
demo package files added
This commit is contained in:
41
SQLinDS/000_libname/dssql.sas
Normal file
41
SQLinDS/000_libname/dssql.sas
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*** HELP START ***/
|
||||||
|
|
||||||
|
/* >>> dsSQL library: <<<
|
||||||
|
*
|
||||||
|
* The dsSQL library stores temporary views
|
||||||
|
* generated during %SQL() macro's execution.
|
||||||
|
* If possible, created as a subdirectory of WORK:
|
||||||
|
|
||||||
|
options dlCreateDir;
|
||||||
|
LIBNAME dsSQL BASE "%sysfunc(pathname(WORK))/dsSQLtmp";
|
||||||
|
|
||||||
|
* if not then redirected to WORK
|
||||||
|
|
||||||
|
LIBNAME dsSQL BASE "%sysfunc(pathname(WORK))";
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*** HELP END ***/
|
||||||
|
|
||||||
|
data WORK._%sysfunc(datetime(), hex16.)_;
|
||||||
|
length option $ 64;
|
||||||
|
option = getoption("dlCreateDir");
|
||||||
|
run;
|
||||||
|
|
||||||
|
options dlCreateDir;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
set _LAST_;
|
||||||
|
rc1 = LIBNAME("dsSQL", "%sysfunc(pathname(work))/dsSQLtmp", "BASE");
|
||||||
|
rc2 = LIBREF("dsSQL");
|
||||||
|
if rc2 NE 0 then
|
||||||
|
rc1 = LIBNAME("dsSQL", "%sysfunc(pathname(work))", "BASE");
|
||||||
|
call execute ("options " || strip(option) || ";");
|
||||||
|
run;
|
||||||
|
|
||||||
|
proc delete data = _last_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
libname dsSQL LIST;
|
||||||
|
;
|
||||||
|
|
||||||
29
SQLinDS/001_macro/dssql_inner.sas
Normal file
29
SQLinDS/001_macro/dssql_inner.sas
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*** HELP START ***/
|
||||||
|
|
||||||
|
/* >>> %dsSQL_Inner() macro: <<<
|
||||||
|
*
|
||||||
|
* Internal macro called by dsSQL() function.
|
||||||
|
*
|
||||||
|
* Recomnended 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 ***/
|
||||||
|
|
||||||
|
/* inner macro */
|
||||||
|
%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;
|
||||||
50
SQLinDS/001_macro/sql.sas
Normal file
50
SQLinDS/001_macro/sql.sas
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*** HELP START ***/
|
||||||
|
|
||||||
|
/* >>> %SQL() macro: <<<
|
||||||
|
*
|
||||||
|
* Main macro which allows to use
|
||||||
|
* SQL's queries in the data step.
|
||||||
|
* Recomnended 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
|
||||||
|
*
|
||||||
|
* EXAMPLE 1: simple sql querry
|
||||||
|
|
||||||
|
data class_subset;
|
||||||
|
set %SQL(select name, sex, height from sashelp.class where age > 12);
|
||||||
|
run;
|
||||||
|
|
||||||
|
* EXAMPLE 2: with dataset options
|
||||||
|
|
||||||
|
data renamed;
|
||||||
|
set %SQL(select * from sashelp.class where sex = "F")(rename = (age=age2));
|
||||||
|
run;
|
||||||
|
|
||||||
|
* EXAMPLE 3: dictionaries in datastep
|
||||||
|
|
||||||
|
data dictionary;
|
||||||
|
set %SQL(select * from dictionary.macros);
|
||||||
|
run;
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*** HELP END ***/
|
||||||
|
|
||||||
|
|
||||||
|
/* outer macro */
|
||||||
|
%MACRO SQL() / PARMBUFF SECURE;
|
||||||
|
%let SYSPBUFF = %superq(SYSPBUFF); /* macroquoting */
|
||||||
|
%let SYSPBUFF = %substr(&SYSPBUFF, 2, %LENGTH(&SYSPBUFF) - 2); /* remove brackets */
|
||||||
|
%let SYSPBUFF = %superq(SYSPBUFF); /* macroquoting */
|
||||||
|
%let SYSPBUFF = %sysfunc(quote(&SYSPBUFF)); /* quotes */
|
||||||
|
%put NOTE-***the querry***; /* print out the querry in the log */
|
||||||
|
%put NOTE-&SYSPBUFF.;
|
||||||
|
%put NOTE-****************;
|
||||||
|
|
||||||
|
%local UNIQUE_INDEX; /* internal variable, a unique index for views */
|
||||||
|
%let UNIQUE_INDEX = &SYSINDEX;
|
||||||
|
%sysfunc(dsSQL(&UNIQUE_INDEX, &SYSPBUFF)) /* <-- call dsSQL() function,
|
||||||
|
see the WORK.SQLinDSfcmp dataset */
|
||||||
|
%MEND SQL;
|
||||||
40
SQLinDS/002_function/dssql.sas
Normal file
40
SQLinDS/002_function/dssql.sas
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*** HELP START ***/
|
||||||
|
|
||||||
|
/* >>> dsSQL() function: <<<
|
||||||
|
*
|
||||||
|
* Internal function called by %SQL() macro.
|
||||||
|
*
|
||||||
|
* Recomnended 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 ***/
|
||||||
|
|
||||||
|
proc fcmp
|
||||||
|
inlib = work.&packageName.fcmp
|
||||||
|
outlib = work.&packageName.fcmp.package
|
||||||
|
;
|
||||||
|
function dsSQL(unique_index_2, query $) $ 41;
|
||||||
|
length
|
||||||
|
query query_arg $ 32000 /* max querry length */
|
||||||
|
viewname $ 41
|
||||||
|
;
|
||||||
|
query_arg = dequote(query);
|
||||||
|
rc = run_macro('dsSQL_Inner' /* <-- inner macro */
|
||||||
|
,unique_index_2
|
||||||
|
,query_arg
|
||||||
|
,viewname
|
||||||
|
);
|
||||||
|
if rc = 0 then return(trim(viewname));
|
||||||
|
else
|
||||||
|
do;
|
||||||
|
put 'ERROR:[function dsSQL] A problem with the dsSQL() function';
|
||||||
|
return(" ");
|
||||||
|
end;
|
||||||
|
endsub;
|
||||||
|
run;
|
||||||
|
quit;
|
||||||
36
SQLinDS/description.sas
Normal file
36
SQLinDS/description.sas
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/* This is the description file for the package. */
|
||||||
|
/* The collon (:) is a field separator and is restricted */
|
||||||
|
/* in lines of the header part. */
|
||||||
|
|
||||||
|
/* **HEADER** */
|
||||||
|
Type: Package :/*required, not null, constant value*/
|
||||||
|
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*/
|
||||||
|
Version: 1.0 :/*required, not null*/
|
||||||
|
Author: Mike Rhoads (RhoadsM1@Westat.com) :/*required, not null*/
|
||||||
|
Maintainer: Bartosz Jablonski (yabwon@gmail.com) :/*required, not null*/
|
||||||
|
License: MIT :/*required, not null, values: MIT, GPL2, BSD, etc.*/
|
||||||
|
Encoding: UTF8 :/*required, not null, values: UTF8, WLATIN1, LATIN2, etc. */
|
||||||
|
|
||||||
|
Required: "Base SAS Software" :/*optional, COMMA separated, QUOTED list, values must be like from proc setinit;run; output */
|
||||||
|
|
||||||
|
/* **DESCRIPTION** */
|
||||||
|
/* All the text below will be used in help */
|
||||||
|
DESCRIPTION START:
|
||||||
|
|
||||||
|
The SQLinDS package is an implementation of
|
||||||
|
the macro-function-sandwich concept introduced in:
|
||||||
|
"Use the Full Power of SAS in Your Function-Style Macros"
|
||||||
|
the article by Mike Rhoads, Westat, Rockville, MD
|
||||||
|
|
||||||
|
Copy of the article can be found at:
|
||||||
|
https://support.sas.com/resources/papers/proceedings12/004-2012.pdf
|
||||||
|
|
||||||
|
SQLinDS package provides following components:
|
||||||
|
1) %dsSQL_inner() macro
|
||||||
|
2) dsSQL() function
|
||||||
|
3) %SQL() macro
|
||||||
|
|
||||||
|
Library DSSQL is created in a subdirectory of the WORK library.
|
||||||
|
|
||||||
|
DESCRIPTION END:
|
||||||
23
SQLinDS/generate_package_sqlinds.sas
Normal file
23
SQLinDS/generate_package_sqlinds.sas
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
%include "C:\SAS_PACKAGES\generatePackage.sas";
|
||||||
|
|
||||||
|
ods html;
|
||||||
|
%generatePackge(filesLocation=C:\SAS_PACKAGES\SQLinDS)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* filename reference "packages" and "package" are keywords;
|
||||||
|
* the first one should be used to point folder with packages;
|
||||||
|
* the second is used internaly by macros;
|
||||||
|
|
||||||
|
filename packages "C:\SAS_PACKAGES";
|
||||||
|
%include packages(loadpackage.sas);
|
||||||
|
|
||||||
|
dm 'log;clear';
|
||||||
|
%loadpackage(SQLinDS)
|
||||||
|
|
||||||
|
%helpPackage(SQLinDS)
|
||||||
|
%helpPackage(SQLinDS,*)
|
||||||
|
|
||||||
|
%unloadPackage(SQLinDS)
|
||||||
|
*/
|
||||||
19
SQLinDS/license.sas
Normal file
19
SQLinDS/license.sas
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2012 Mike Rhoads
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
82
SQLinDS/macrofunctionsandwich.sas
Normal file
82
SQLinDS/macrofunctionsandwich.sas
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
|
||||||
|
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