Macros for SAS Application Developers
https://github.com/sasjs/core
Loading...
Searching...
No Matches
mp_hashdataset.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Returns a unique hash for a dataset
4 @details Ignores metadata attributes, used only to hash values. If used to
5 compare datasets, they must have their columns and rows in the same order.
6
7 %mp_hashdataset(sashelp.class,outds=myhash)
8
9 data _null_;
10 set work.myhash;
11 put hashkey=;
12 run;
13
14 ![sas md5 hash dataset log results](https://i.4gl.io/1/KorUKoyE05.png/raw)
15
16 <h4> SAS Macros </h4>
17 @li mf_getattrn.sas
18 @li mf_getuniquename.sas
19 @li mf_getvarlist.sas
20 @li mp_md5.sas
21
22 <h4> Related Files </h4>
23 @li mp_hashdataset.test.sas
24 @li mp_hashdirectory.sas
25
26 @param [in] libds dataset to hash
27 @param [in] salt= () Provide a salt (could be, for instance, the dataset name)
28 @param [in] iftrue= (1=1) A condition under which the macro should be executed
29 @param [out] outds= (work._data_) The output dataset to create. This
30 will contain one column (hashkey) with one observation (a $hex32.
31 representation of the input hash)
32 |hashkey:$32.|
33 |---|
34 |28ABC74ABFC45F50794237BA5566E6CA|
35
36 @version 9.2
37 @author Allan Bowe
38**/
39
40%macro mp_hashdataset(
41 libds,
42 outds=work._data_,
43 salt=,
44 iftrue=%str(1=1)
45)/*/STORE SOURCE*/;
46
47%local keyvar /* roll up the md5 */
48 prevkeyvar /* retain prev record md5 */
49 lastvar /* last var in input ds */
50 cvars nvars;
51
52%if not(%eval(%unquote(&iftrue))) %then %return;
53
54/* avoid naming conflict for hash key vars */
55%let keyvar=%mf_getuniquename();
56%let prevkeyvar=%mf_getuniquename();
57%let lastvar=%mf_getuniquename();
58
59%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
60 data &outds;
61 length hashkey $32;
62 hashkey=put(md5("&salt"),$hex32.);
63 output;
64 stop;
65 run;
66 %put &sysmacroname: Dataset &libds is empty, or is not a dataset;
67 %put &sysmacroname: hashkey of &outds is based on salt (&salt) only;
68%end;
69%else %if %mf_getattrn(&libds,NLOBS)<0 %then %do;
70 %put %str(ERR)OR: Dataset &libds is not a dataset;
71%end;
72%else %do;
73 data &outds(rename=(&keyvar=hashkey) keep=&keyvar)
74 %if "%substr(&sysver,1,1)" ne "4" and "%substr(&sysver,1,1)" ne "5" %then %do;
75 /nonote2err
76 %end;
77 ;
78 length &prevkeyvar &keyvar $32;
79 retain &prevkeyvar;
80 if _n_=1 then &prevkeyvar=put(md5("&salt"),$hex32.);
81 set &libds end=&lastvar;
82 /* hash should include previous row */
83 &keyvar=%mp_md5(
84 cvars=%mf_getvarlist(&libds,typefilter=C) &prevkeyvar,
85 nvars=%mf_getvarlist(&libds,typefilter=N)
86 );
87 &prevkeyvar=&keyvar;
88 if &lastvar then output;
89 run;
90%end;
91%mend mp_hashdataset;