mpe_derived used &dc_dttmtfmt in its where= but the guard only checked libds and dclib, so an unset value turned the filter into 'lt tx_to' and the control-table step failed with a syntax error a long way from the cause. It is now part of the guard, named in the message. The 7.19 migration took max(selectbox_rk) into a macro variable, which is missing on an install whose MPE_SELECTBOX is still empty - %eval(&maxrk+1) then fails. coalesce(max(selectbox_rk),0) makes the first row start at 1.
193 lines
7.1 KiB
SAS
193 lines
7.1 KiB
SAS
/**
|
|
@file
|
|
@brief migration script to move to v7.19 of Data Controller
|
|
|
|
REQUIRED CHANGE - adds the MPE_DERIVED table, which holds derived (computed)
|
|
variable definitions for the EDIT screen, and registers it in MPE_TABLES so
|
|
that it can be maintained through the app with the usual approve workflow.
|
|
|
|
Replace YOURDCLIB and the library path below, then run the script. Any
|
|
MPE_DERIVED rows added before this script runs will be lost when the table
|
|
is created, so run it before configuring any derived variables.
|
|
|
|
**/
|
|
|
|
%let dclib=YOURDCLIB;
|
|
|
|
libname &dclib "/YOUR/DATACONTROLLER/LIBRARY/PATH";
|
|
|
|
proc sql;
|
|
create table &dclib..mpe_derived
|
|
(
|
|
tx_from num not null format=datetime19.3,
|
|
libref varchar(8) not null,
|
|
dsn varchar(32) not null,
|
|
var_nm varchar(32) not null,
|
|
var_deps varchar(4000),
|
|
var_type varchar(1) not null,
|
|
var_len num not null,
|
|
var_fmt varchar(32),
|
|
var_label varchar(256),
|
|
var_logic varchar(4000) not null,
|
|
active num not null,
|
|
tx_to num not null format=datetime19.3
|
|
);
|
|
quit;
|
|
|
|
proc datasets lib=&dclib noprint;
|
|
modify mpe_derived;
|
|
index create
|
|
pk_mpe_derived=(tx_from libref dsn var_nm)
|
|
/nomiss unique;
|
|
quit;
|
|
|
|
proc sql;
|
|
insert into &dclib..mpe_tables
|
|
set tx_from=0
|
|
,tx_to='31DEC5999:23:59:59'dt
|
|
,libref="&dclib"
|
|
,dsn='MPE_DERIVED'
|
|
,num_of_approvals_required=1
|
|
,loadtype='TXTEMPORAL'
|
|
,buskey='LIBREF DSN VAR_NM'
|
|
,post_edit_hook='services/hooks/mpe_derived_postedit'
|
|
,notes='Derived (computed) variables for the EDIT screen'
|
|
,var_txfrom='TX_FROM'
|
|
,var_txto='TX_TO'
|
|
;
|
|
quit;
|
|
|
|
/* Dropdown values for VAR_TYPE and ACTIVE. These rows, and the field rules
|
|
* further down, mirror the MPE_DERIVED rows in mpe_makedata.sas - keep the two
|
|
* in step, or an upgraded install and a freshly seeded one behave differently. */
|
|
proc sql noprint;
|
|
/* coalesce: an install with no selectbox rows yet returns a missing value,
|
|
and %eval(&maxrk+1) below would then fail */
|
|
select coalesce(max(selectbox_rk),0) into: maxrk from &dclib..mpe_selectbox;
|
|
quit;
|
|
|
|
%let rk1=%eval(&maxrk+1);
|
|
%let rk2=%eval(&maxrk+2);
|
|
%let rk3=%eval(&maxrk+3);
|
|
%let rk4=%eval(&maxrk+4);
|
|
|
|
proc sql;
|
|
insert into &dclib..mpe_selectbox
|
|
set selectbox_rk=&rk1
|
|
,ver_from_dttm=0
|
|
,select_lib="&dclib"
|
|
,select_ds="MPE_DERIVED"
|
|
,base_column="VAR_TYPE"
|
|
,selectbox_value='C'
|
|
,selectbox_order=1
|
|
,ver_to_dttm='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..mpe_selectbox
|
|
set selectbox_rk=&rk2
|
|
,ver_from_dttm=0
|
|
,select_lib="&dclib"
|
|
,select_ds="MPE_DERIVED"
|
|
,base_column="VAR_TYPE"
|
|
,selectbox_value='N'
|
|
,selectbox_order=2
|
|
,ver_to_dttm='31DEC5999:23:59:59'dt;
|
|
/* ACTIVE - a fixed pair, not a lookup against another table */
|
|
insert into &dclib..mpe_selectbox
|
|
set selectbox_rk=&rk3
|
|
,ver_from_dttm=0
|
|
,select_lib="&dclib"
|
|
,select_ds="MPE_DERIVED"
|
|
,base_column="ACTIVE"
|
|
,selectbox_value='1'
|
|
,selectbox_order=1
|
|
,ver_to_dttm='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..mpe_selectbox
|
|
set selectbox_rk=&rk4
|
|
,ver_from_dttm=0
|
|
,select_lib="&dclib"
|
|
,select_ds="MPE_DERIVED"
|
|
,base_column="ACTIVE"
|
|
,selectbox_value='0'
|
|
,selectbox_order=2
|
|
,ver_to_dttm='31DEC5999:23:59:59'dt;
|
|
quit;
|
|
|
|
/* Field rules for the EDIT screen. These are client side - the server side
|
|
* enforcement is the post edit hook registered above. */
|
|
proc sql;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="LIBREF"
|
|
,rule_type='CASE',rule_value='UPCASE',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
/* the libraries the user can edit, as MPE_VALIDATIONS.BASE_LIB does */
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="LIBREF"
|
|
,rule_type='SOFTSELECT_HOOK'
|
|
,rule_value="services/validations/libraries_editable"
|
|
,rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="DSN"
|
|
,rule_type='CASE',rule_value='UPCASE',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
/* tables in the LIBREF on the same row - the hook reads it from source_row */
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="DSN"
|
|
,rule_type='SOFTSELECT_HOOK'
|
|
,rule_value="services/validations/tables_editable"
|
|
,rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_NM"
|
|
,rule_type='CASE',rule_value='UPCASE',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_NM"
|
|
,rule_type='HARDREGEX',rule_value='^[A-Za-z_][A-Za-z0-9_]*$',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_DEPS"
|
|
,rule_type='CASE',rule_value='UPCASE',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_DEPS"
|
|
,rule_type='HARDREGEX',rule_value='^[A-Za-z0-9_ ]*$',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_TYPE"
|
|
,rule_type='CASE',rule_value='UPCASE',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_TYPE"
|
|
,rule_type='HARDSELECT',rule_value=' ',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
/* ACTIVE has no NOTNULL rule: the column is NOT NULL in the model, and the
|
|
* EDIT screen offers the MPE_SELECTBOX values for it. */
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_LEN"
|
|
,rule_type='MINVAL',rule_value='1',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_LEN"
|
|
,rule_type='MAXVAL',rule_value='32767',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_FMT"
|
|
,rule_type='CASE',rule_value='UPCASE',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_FMT"
|
|
,rule_type='HARDREGEX'
|
|
,rule_value='^(\$?[A-Za-z][A-Za-z0-9_]*(\.[0-9]+)?\.?|\$?[0-9]+(\.[0-9]+)?\.?)?$',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_LABEL"
|
|
,rule_type='HARDREGEX'
|
|
,rule_value='^[^\x00-\x1F\x7F]*$',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
insert into &dclib..MPE_VALIDATIONS set
|
|
tx_from=0,base_lib="&dclib",base_ds="MPE_DERIVED",base_col="VAR_LOGIC"
|
|
,rule_type='HARDREGEX'
|
|
,rule_value='^(?!.*(/\*|\*/))[^;&%]*$',rule_active=1
|
|
,tx_to='31DEC5999:23:59:59'dt;
|
|
quit;
|