211%macro mp_stackdiffs(baselibds
215 ,processed_dttm_var=0
222%
if &mdebug=1 %then %
do;
223 %put &sysmacroname entry vars:;
229%mp_abort(iftrue= (%mf_islibds(&baselibds) ne 1)
231 ,msg=%str(Invalid baselibds: &baselibds)
233%mp_abort(iftrue= (%mf_islibds(&auditlibds) ne 1)
235 ,msg=%str(Invalid auditlibds: &auditlibds)
237%mp_abort(iftrue= (%length(&key)=0)
239 ,msg=%str(Missing key variables!)
242 %mf_existVarList(&auditlibds,LIBREF DSN MOVE_TYPE KEY_HASH TGTVAR_NM IS_PK
243 IS_DIFF TGTVAR_TYPE OLDVAL_NUM NEWVAL_NUM OLDVAL_CHAR NEWVAL_CHAR)=0
246 ,msg=%str(Input &auditlibds is missing required columns!)
251%local prefix dslist x var keyjoin commakey keepvars missvars fref;
252%let prefix=%substr(%mf_getuniquename(),1,25);
253%let dslist=ds1d ds2d ds3d ds1a ds2a ds3a ds1m ds2m ds3m pks dups base
254 delrec delerr addrec adderr modrec moderr;
255%
do x=1 %to %sysfunc(countw(&dslist));
256 %let var=%scan(&dslist,&x);
258 %let &var=%upcase(&prefix._&var);
261%let key=%upcase(&key);
262%let commakey=%mf_getquotedstr(&key,quote=N);
265%
do x=1 %to %sysfunc(countw(&key));
266 %let var=%scan(&key,&x);
267 %let keyjoin=&keyjoin and a.&var=b.&var;
271 length pk_vars $256 pk_vals $4098 err_msg $512;
272 call missing (of _all_);
280%let keepvars=MOVE_TYPE KEY_HASH TGTVAR_NM TGTVAR_TYPE IS_PK
281 OLDVAL_NUM OLDVAL_CHAR
282 NEWVAL_NUM NEWVAL_CHAR;
283proc sort data=&auditlibds(where=(move_type=
'D') keep=&keepvars)
284 out=&ds1d(drop=move_type);
285by KEY_HASH TGTVAR_NM;
287proc transpose data=&ds1d(where=(tgtvar_type=
'N'))
288 out=&ds2d(drop=_name_);
293proc transpose data=&ds1d(where=(tgtvar_type='C'))
294 out=&ds3d(drop=_name_);
299%mp_ds2squeeze(&ds2d,outds=&ds2d)
300%mp_ds2squeeze(&ds3d,outds=&ds3d)
302 if 0 then set &baselibds;
306 if not missing(%scan(&key,1));
316proc sort data=&auditlibds(where=(move_type='A') keep=&keepvars)
317 out=&ds1a(drop=move_type);
318 by KEY_HASH TGTVAR_NM;
320proc transpose data=&ds1a(where=(tgtvar_type='N'))
321 out=&ds2a(drop=_name_);
326proc transpose data=&ds1a(where=(tgtvar_type='C'))
327 out=&ds3a(drop=_name_);
332%mp_ds2squeeze(&ds2a,outds=&ds2a)
333%mp_ds2squeeze(&ds3a,outds=&ds3a)
335 if 0 then set &baselibds;
339 if not missing(%scan(&key,1));
349proc sort data=&auditlibds(
350 where=(move_type='M' and is_pk=1) keep=&keepvars
351 ) out=&ds1m(drop=move_type);
352 by KEY_HASH TGTVAR_NM;
354proc transpose data=&ds1m(where=(tgtvar_type='N'))
355 out=&ds2m(drop=_name_);
360proc transpose data=&ds1m(where=(tgtvar_type='C'))
361 out=&ds3m(drop=_name_);
366%mp_ds2squeeze(&ds2m,outds=&ds2m)
367%mp_ds2squeeze(&ds3m,outds=&ds3m)
369 if 0 then set &baselibds;
372 if not missing(%scan(&key,1));
385 if 0 then set &baselibds;
386 set &outadd &outmod &outdel;
390proc sort noduprec dupout=&dups;
397%mp_abort(iftrue= (%mf_nobs(&dups) ne 0)
399 ,msg=%str(duplicates (%mf_nobs(&dups)) found on &auditlibds!)
405 from &baselibds a, &pks b
413create table &delrec as
418 where b.%scan(&key,1) is null
422 if 0 then set &errds;
425 PK_VALS=catx('/',&commakey);
426 ERR_MSG="Rows cannot be deleted as they do not exist on the Base dataset";
427 keep PK_VARS PK_VALS ERR_MSG;
429proc append base=&errds data=&delerr;
433 merge &outdel (in=a) &delrec (in=b);
442%let missvars=%mf_wordsinstr1butnotstr2(
443 Str1=%upcase(%mf_getvarlist(&outadd)),
444 Str2=%upcase(%mf_getvarlist(&baselibds))
446%if %length(&missvars)>0 %then %do;
449 if 0 then set &errds;
452 PK_VALS=catx('/',&commakey);
453 ERR_MSG="Rows cannot be added due to missing base vars: &missvars";
454 keep PK_VARS PK_VALS ERR_MSG;
456 proc append base=&errds data=&adderr;
459 delete * from &outadd;
464 create table &addrec as
473 if 0 then set &errds;
476 PK_VALS=catx('/',&commakey);
477 ERR_MSG="Rows cannot be added as they already exist on the Base dataset";
478 keep PK_VARS PK_VALS ERR_MSG;
480 proc append base=&errds data=&adderr;
485 merge &outadd (in=a) &addrec (in=b);
496select distinct tgtvar_nm into: missvars separated by ' '
498 where move_type='M' and is_diff=1;
499%let missvars=%mf_wordsinstr1butnotstr2(
501 Str2=%upcase(%mf_getvarlist(&baselibds))
503%if %length(&missvars)>0 %then %do;
506 if 0 then set &errds;
509 PK_VALS=catx('/',&commakey);
510 ERR_MSG="Rows cannot be modified due to missing base vars: &missvars";
511 keep PK_VARS PK_VALS ERR_MSG;
513 proc append base=&errds data=&moderr;
516 delete * from &outmod;
521 create table &modrec as
526 where b.%scan(&key,1) is null
529 if 0 then set &errds;
532 PK_VALS=catx('/',&commakey);
533 ERR_MSG="Rows cannot be modified as they do not exist on the Base dataset";
534 keep PK_VARS PK_VALS ERR_MSG;
536 proc append base=&errds data=&moderr;
540 merge &outmod (in=a) &modrec (in=b);
545 proc sql undo_policy=none;
546 create table &outmod as
554 %let fref=%mf_getuniquefileref();
557 set &auditlibds(where=(move_type='M')) end=lastobs;
560 if _n_=1 then put 'proc sql;';
561 if first.key_hash then do;
563 put "update &outmod set " @@;
565 if is_diff=1 then do;
566 if comma='N' then do;
571 if tgtvar_type='C' then do;
573 qstr=quote(trim(NEWVAL_CHAR));
574 put tgtvar_nm '=' qstr;
576 else put tgtvar_nm '=' newval_num;
577 if comma=' ' then comma=' ,';
579 if last.key_hash then put ' where key_hash=trim("' key_hash '");';
580 if lastobs then put "alter table &outmod drop key_hash;";
585%if &mdebug=0 %then %do;
586 proc datasets lib=work;
589 %put &sysmacroname exit vars:;