Production Ready Macros for SAS Application Developers
https://github.com/sasjs/core
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. Compared
5 datasets must be 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.imgur.com/MqF98vk.png)
15
16 <h4> SAS Macros </h4>
17 @li mf_getattrn.sas
18 @li mf_getuniquename.sas
19 @li mf_getvarlist.sas
20 @li mf_getvartype.sas
21
22 @param [in] libds dataset to hash
23 @param [in] salt= Provide a salt (could be, for instance, the dataset name)
24 @param [out] outds= (work.mf_hashdataset) The output dataset to create. This
25 will contain one column (hashkey) with one observation (a hex32.
26 representation of the input hash)
27 |hashkey:$32.|
28 |---|
29 |28ABC74ABFC45F50794237BA5566E6CA|
30
31 @version 9.2
32 @author Allan Bowe
33**/
34
35%macro mp_hashdataset(
36 libds,
37 outds=,
38 salt=
39)/*/STORE SOURCE*/;
40 %if %mf_getattrn(&libds,NLOBS)=0 %then %do;
41 %put %str(WARN)ING: Dataset &libds is empty;, or is not a dataset;
42 %end;
43 %else %if %mf_getattrn(&libds,NLOBS)<0 %then %do;
44 %put %str(ERR)OR: Dataset &libds is not a dataset;
45 %end;
46 %else %do;
47 %local keyvar /* roll up the md5 */
48 prevkeyvar /* retain prev record md5 */
49 lastvar /* last var in input ds */
50 varlist var i;
51 /* avoid naming conflict for hash key vars */
52 %let keyvar=%mf_getuniquename();
53 %let prevkeyvar=%mf_getuniquename();
54 %let lastvar=%mf_getuniquename();
55 %let varlist=%mf_getvarlist(&libds);
56 data &outds(rename=(&keyvar=hashkey) keep=&keyvar);
57 length &prevkeyvar &keyvar $32;
58 retain &prevkeyvar "%sysfunc(md5(%str(&salt)),$hex32.)";
59 set &libds end=&lastvar;
60 /* hash should include previous row */
61 &keyvar=put(md5(&prevkeyvar
62 /* loop every column, hashing every individual value */
63 %do i=1 %to %sysfunc(countw(&varlist));
64 %let var=%scan(&varlist,&i,%str( ));
65 %if %mf_getvartype(&libds,&var)=C %then %do;
66 !!put(md5(trim(&var)),$hex32.)
67 %end;
68 %else %do;
69 !!put(md5(trim(put(&var*1,binary64.))),$hex32.)
70 %end;
71 %end;
72 ),$hex32.);
73 &prevkeyvar=&keyvar;
74 if &lastvar then output;
75 run;
76 %end;
77%mend mp_hashdataset;