213%macro mp_stackdiffs(baselibds
217 ,processed_dttm_var=0
224%
if &mdebug=1 %then %
do;
225 %put &sysmacroname entry vars:;
231%mp_abort(iftrue= (%mf_islibds(&baselibds) ne 1)
233 ,msg=%str(Invalid baselibds: &baselibds)
235%mp_abort(iftrue= (%mf_islibds(&auditlibds) ne 1)
237 ,msg=%str(Invalid auditlibds: &auditlibds)
239%mp_abort(iftrue= (%length(&key)=0)
241 ,msg=%str(Missing key variables!)
244 %mf_existVarList(&auditlibds,LIBREF DSN MOVE_TYPE KEY_HASH TGTVAR_NM IS_PK
245 IS_DIFF TGTVAR_TYPE OLDVAL_NUM NEWVAL_NUM OLDVAL_CHAR NEWVAL_CHAR)=0
248 ,msg=%str(Input &auditlibds is missing required columns!)
253%local prefix dslist x var keyjoin commakey keepvars missvars fref;
254%let prefix=%substr(%mf_getuniquename(),1,25);
255%let dslist=ds1d ds2d ds3d ds1a ds2a ds3a ds1m ds2m ds3m pks dups base
256 delrec delerr addrec adderr modrec moderr;
257%
do x=1 %to %sysfunc(countw(&dslist));
258 %let var=%scan(&dslist,&x);
260 %let &var=%upcase(&prefix._&var);
263%let key=%upcase(&key);
264%let commakey=%mf_getquotedstr(&key,quote=N);
267%
do x=1 %to %sysfunc(countw(&key));
268 %let var=%scan(&key,&x);
269 %let keyjoin=&keyjoin and a.&var=b.&var;
273 length pk_vars $256 pk_vals $4098 err_msg $512;
274 call missing (of _all_);
282%let keepvars=MOVE_TYPE KEY_HASH TGTVAR_NM TGTVAR_TYPE IS_PK
283 OLDVAL_NUM OLDVAL_CHAR
284 NEWVAL_NUM NEWVAL_CHAR;
285proc sort data=&auditlibds(where=(move_type=
'D') keep=&keepvars)
286 out=&ds1d(drop=move_type);
287by KEY_HASH TGTVAR_NM;
289proc transpose data=&ds1d(where=(tgtvar_type=
'N'))
290 out=&ds2d(drop=_name_);
295proc transpose data=&ds1d(where=(tgtvar_type=
'C'))
296 out=&ds3d(drop=_name_);
301%mp_ds2squeeze(&ds2d,outds=&ds2d)
302%mp_ds2squeeze(&ds3d,outds=&ds3d)
304 if 0 then set &baselibds;
308 if not missing(%scan(&key,1));
318proc sort data=&auditlibds(where=(move_type=
'A') keep=&keepvars)
319 out=&ds1a(drop=move_type);
320 by KEY_HASH TGTVAR_NM;
322proc transpose data=&ds1a(where=(tgtvar_type=
'N'))
323 out=&ds2a(drop=_name_);
328proc transpose data=&ds1a(where=(tgtvar_type=
'C'))
329 out=&ds3a(drop=_name_);
334%mp_ds2squeeze(&ds2a,outds=&ds2a)
335%mp_ds2squeeze(&ds3a,outds=&ds3a)
337 if 0 then set &baselibds;
341 if not missing(%scan(&key,1));
351proc sort data=&auditlibds(
352 where=(move_type=
'M' and is_pk=1) keep=&keepvars
353 ) out=&ds1m(drop=move_type);
354 by KEY_HASH TGTVAR_NM;
356proc transpose data=&ds1m(where=(tgtvar_type=
'N'))
357 out=&ds2m(drop=_name_);
362proc transpose data=&ds1m(where=(tgtvar_type=
'C'))
363 out=&ds3m(drop=_name_);
368%mp_ds2squeeze(&ds2m,outds=&ds2m)
369%mp_ds2squeeze(&ds3m,outds=&ds3m)
371 if 0 then set &baselibds;
374 if not missing(%scan(&key,1));
387 if 0 then set &baselibds;
388 set &outadd &outmod &outdel;
392proc sort noduprec dupout=&dups;
399%mp_abort(iftrue= (%mf_nobs(&dups) ne 0)
401 ,msg=%str(duplicates (%mf_nobs(&dups)) found on &auditlibds!)
407 from &baselibds a, &pks b
415create table &delrec as
420 where b.%scan(&key,1) is null
424 if 0 then set &errds;
427 PK_VALS=catx(
'/',&commakey);
428 ERR_MSG=
"Rows cannot be deleted as they do not exist on the Base dataset";
429 keep PK_VARS PK_VALS ERR_MSG;
431proc append base=&errds data=&delerr;
435 merge &outdel (in=a) &delrec (in=b);
444%let missvars=%mf_wordsinstr1butnotstr2(
445 Str1=%upcase(%mf_getvarlist(&outadd)),
446 Str2=%upcase(%mf_getvarlist(&baselibds))
448%if %length(&missvars)>0 %then %do;
451 if 0 then set &errds;
454 PK_VALS=catx(
'/',&commakey);
455 ERR_MSG=
"Rows cannot be added due to missing base vars: &missvars";
456 keep PK_VARS PK_VALS ERR_MSG;
458 proc append base=&errds data=&adderr;
461 delete * from &outadd;
466 create table &addrec as
475 if 0 then set &errds;
478 PK_VALS=catx(
'/',&commakey);
479 ERR_MSG=
"Rows cannot be added as they already exist on the Base dataset";
480 keep PK_VARS PK_VALS ERR_MSG;
482 proc append base=&errds data=&adderr;
487 merge &outadd (in=a) &addrec (in=b);
498select distinct tgtvar_nm into: missvars separated by
' '
500 where move_type=
'M' and is_diff=1;
501%let missvars=%mf_wordsinstr1butnotstr2(
503 Str2=%upcase(%mf_getvarlist(&baselibds))
505%if %length(&missvars)>0 %then %do;
508 if 0 then set &errds;
511 PK_VALS=catx(
'/',&commakey);
512 ERR_MSG=
"Rows cannot be modified due to missing base vars: &missvars";
513 keep PK_VARS PK_VALS ERR_MSG;
515 proc append base=&errds data=&moderr;
518 delete * from &outmod;
523 create table &modrec as
528 where b.%scan(&key,1) is null
531 if 0 then set &errds;
534 PK_VALS=catx(
'/',&commakey);
535 ERR_MSG=
"Rows cannot be modified as they do not exist on the Base dataset";
536 keep PK_VARS PK_VALS ERR_MSG;
538 proc append base=&errds data=&moderr;
542 merge &outmod (in=a) &modrec (in=b);
547 proc sql undo_policy=none;
548 create table &outmod as
556 %let fref=%mf_getuniquefileref();
559 set &auditlibds(where=(move_type=
'M')) end=lastobs;
562 if _n_=1 then put 'proc sql;';
563 if first.key_hash then do;
565 put
"update &outmod set " @@;
567 if is_diff=1 then do;
568 if comma=
'N' then do;
573 if tgtvar_type=
'C' then do;
575 qstr=quote(trim(NEWVAL_CHAR));
576 put tgtvar_nm
'=' qstr;
582 put tgtvar_nm
'=' @@;
583 if missing(newval_num) and newval_num ne . then put
"." newval_num;
586 if comma=' ' then comma=' ,';
588 if last.key_hash then put ' where key_hash=trim(
"' key_hash '");';
589 if lastobs then put
"alter table &outmod drop key_hash;";
594%if &mdebug=0 %then %do;
595 proc datasets lib=work;
598 %put &sysmacroname exit vars:;