A table's metadata columns are named per table - VAR_TXFROM, VAR_TXTO and VAR_PROCESSED in MPE_TABLES hold those names, and they can be anything (the bitemporal demo table uses VER_FROM_DTTM and VER_TO_DTTM). When they exist they are physical columns of the target, so the engine's collision check already refuses a VAR_NM that matches one, whatever it is called. The hard-coded list treated three example names as special: it refused them on tables that use other names, and told the reader something untrue about what is reserved.
104 lines
3.6 KiB
SAS
104 lines
3.6 KiB
SAS
/**
|
|
@file
|
|
@brief Generates the SAS statements that create Data Controller derived variables
|
|
@details Derived (computed) variables are configured in MPE_DERIVED. Each
|
|
row defines one variable, which is created in a DATA step view ahead of the
|
|
filter, so that it can be filtered on in the EDIT screen.
|
|
|
|
The engine lives in @sasjs/core as mp_derivedvars - this macro only supplies
|
|
what is specific to Data Controller: the control table name, the bitemporal
|
|
filter that picks the current version of a row, and the list of names that
|
|
belong to the metadata and may not be used as a variable.
|
|
|
|
The macro writes the generated statements to a fileref, so that callers can
|
|
compose them into a view:
|
|
|
|
%mpe_derived(libds=&libds,dclib=&mpelib,outref=dercode)
|
|
data work.vw_derived / view=work.vw_derived;
|
|
set &libds;
|
|
%include dercode;
|
|
run;
|
|
|
|
Alternatively, pass outview= and the macro will build the view itself.
|
|
|
|
The filter must be applied by the caller, in the step that reads the view:
|
|
|
|
data out;
|
|
set work.vw_derived;
|
|
where %inc filtref;;
|
|
run;
|
|
|
|
A WHERE statement applies to the data set named on the SET statement, so it
|
|
cannot reference a variable that is created in the same data step. Applying
|
|
it to the view puts the derived variables on the input, which is what makes
|
|
them filterable.
|
|
|
|
Each statement block is of the form:
|
|
|
|
attrib REGION length=$21 label='REGION=<expression>' format=$21.;
|
|
REGION = <expression>;
|
|
|
|
Type and length are declared by the administrator, so the result is
|
|
deterministic. VAR_LABEL is optional: when it is missing or blank the label
|
|
is the variable name, an equals sign and the expression, otherwise the
|
|
configured label is used as given.
|
|
|
|
VAR_DEPS lists every input the expression uses - physical columns and
|
|
derived variables alike. The statements are generated in dependency order,
|
|
so a derived variable may build on another one without a sequence number
|
|
being maintained. A cycle is rejected.
|
|
|
|
Semicolons, macro triggers and comments are rejected, so a row can only ever
|
|
be an expression. A derived variable may not reuse the name of a physical
|
|
column, and may not reference itself: an intra-row calculation would imply a
|
|
retained value, which depends on the order rows happen to arrive in.
|
|
|
|
<h4> SAS Macros </h4>
|
|
@li mp_derivedvars.sas
|
|
@li mp_abort.sas
|
|
|
|
@param [in] libds= The target table (libref.dataset, lib must be assigned)
|
|
@param [in] dclib= The Data Controller control library
|
|
@param [out] outref= (0) Fileref to receive the generated statements
|
|
@param [out] outvars= (work.derived_vars) Dataset of derived variable names
|
|
@param [in] outview= (0) Optional two-level name for the derived view
|
|
|
|
@version 9.2
|
|
@author 4GL Apps Ltd
|
|
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
|
and may not be re-distributed or re-sold without the express permission of
|
|
4GL Apps Ltd.
|
|
|
|
**/
|
|
|
|
%macro mpe_derived(libds=,
|
|
dclib=,
|
|
outref=0,
|
|
outvars=work.derived_vars,
|
|
outview=0
|
|
);
|
|
|
|
%local reserved;
|
|
|
|
/* the only name that has to be refused outright - the metadata columns of the
|
|
target table are physical columns, so the engine's collision check covers
|
|
them whatever MPE_TABLES calls them */
|
|
%let reserved=%str(_____DELETE__THIS__RECORD_____);
|
|
|
|
%mp_abort(iftrue= (%length(&libds)=0 or %length(&dclib)=0)
|
|
,mac=&sysmacroname
|
|
,msg=%str(Missing: libds dclib)
|
|
)
|
|
|
|
%mp_derivedvars(
|
|
libds=&libds
|
|
,control=&dclib..mpe_derived
|
|
,where=%str(&dc_dttmtfmt lt tx_to and active=1)
|
|
,outref=&outref
|
|
,outvars=&outvars
|
|
,outview=&outview
|
|
,reserved=&reserved
|
|
)
|
|
|
|
%mend mpe_derived;
|