Same rule as the 7.19 hook (PR #366): ACTIVE is NOTNULL + HARDSELECT in the EDIT screen, so the field checks must refuse a missing value or anything other than 0 and 1 - otherwise a direct stagedata submission stages a row the picker would never have allowed. The fixture gains the active column (1 by default, 2 for BADACTIVE) and the count of reported rows goes from five to six.
76 lines
3.4 KiB
SAS
76 lines
3.4 KiB
SAS
/**
|
|
@file
|
|
@brief Field level checks for a staged MPE_DERIVED submission
|
|
@details Writes one row per staged row that breaks a rule, with the reason in
|
|
REASON, so a caller can report the first failure and abort. Rows marked for
|
|
deletion are skipped - they are being removed, so their fields are not loaded.
|
|
|
|
The rules are the ones %mpe_derived applies at read time, so a submission
|
|
cannot stage a row the engine would then refuse.
|
|
|
|
@param inds the staged rows, already normalised by the caller
|
|
@param outds the dataset to create: one row per failing row, plus REASON
|
|
|
|
@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_check(inds=work.staging_ds, outds=work.derived_check);
|
|
data &outds;
|
|
set &inds;
|
|
length reason $200;
|
|
if upcase(_____DELETE__THIS__RECORD_____)='YES' then delete;
|
|
call missing(reason);
|
|
|
|
if missing(libref) or missing(dsn) then reason='LIBREF and DSN are required';
|
|
else if var_nm='' then reason='VAR_NM is required';
|
|
else if verify(strip(var_nm),'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_')>0
|
|
then reason='VAR_NM must be a valid SAS name';
|
|
else if verify(substr(var_nm,1,1),'0123456789')=0
|
|
then reason='VAR_NM must not start with a digit';
|
|
else if var_nm='_____DELETE__THIS__RECORD_____'
|
|
then reason='VAR_NM is reserved';
|
|
else if var_type not in ('C','N')
|
|
then reason='VAR_TYPE must be C or N';
|
|
/* ACTIVE is a picker in the EDIT screen (HARDSELECT over the MPE_SELECTBOX
|
|
pair) - the same pair is enforced here, so a submission that bypasses the
|
|
grid cannot land a value the screen would never offer. */
|
|
else if missing(active) or active not in (0,1)
|
|
then reason='ACTIVE must be 1 or 0';
|
|
else if missing(var_len) or var_len ne int(var_len) or var_len<1
|
|
then reason='VAR_LEN must be a positive integer';
|
|
else if var_type='C' and var_len>32767
|
|
then reason='VAR_LEN exceeds 32767 for a character variable';
|
|
else if var_type='N' and var_len>8
|
|
then reason='VAR_LEN exceeds 8 for a numeric variable';
|
|
else if index(var_fmt,';')>0 or indexc(var_fmt,'&%')>0
|
|
or index(var_fmt,'/*')>0 or index(var_fmt,'*/')>0
|
|
then reason='VAR_FMT must be a format name, without ; & % or /* */';
|
|
else if verify(strip(var_fmt),'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$.')>0
|
|
then reason='VAR_FMT must be a format name';
|
|
/* VAR_LABEL is free text: any character is allowed, in any script, and the
|
|
quotes in it are escaped by %mp_derivedvars when the attrib statement is
|
|
built. What is refused is anything that cannot be a single-line column
|
|
label - a control character or a line break - and a value long enough to
|
|
be cut down silently, since the engine truncates the label to 256. */
|
|
else if anycntrl(var_label)>0
|
|
then reason='VAR_LABEL must be plain text - no line breaks or control characters';
|
|
else if klength(var_label)>256
|
|
then reason='VAR_LABEL exceeds 256 characters';
|
|
else if missing(var_logic)
|
|
then reason='VAR_LOGIC is required';
|
|
else if index(var_logic,';')>0
|
|
then reason='VAR_LOGIC must be a single expression - remove the ;';
|
|
else if indexc(var_logic,'&%')>0
|
|
then reason='VAR_LOGIC must not contain macro triggers';
|
|
else if index(var_logic,'/*')>0 or index(var_logic,'*/')>0
|
|
then reason='VAR_LOGIC must not contain comments';
|
|
|
|
if not missing(reason) then output;
|
|
run;
|
|
|
|
%mend mpe_derived_check;
|