Pages

SyntaxHighlighter

Thursday, May 21, 2020

Future Proofing

It does not happen often, but it does happen. An event such as a server upgrade requires related changes to settings used by programs. Of course, alterations are not merely related to equipment changes but things like name or address changes do happen over time. This blog post reveals one technique to data drive those inevitable changes.

The approach used here was influenced by an equipment upgrade as well as SAS software upgrade from version 9.4m3 to 9.4m6. Instead of writing conditional macro code such as %IF-%THEN/%ELSE, the below code uses a macro function to return the name/value pair result directly inline. This technique is not only much more compact and flexible but it also retains changes over time.

The first thing needed is a permanent SAS data set to retain the values. Below is the structure that I used to support changes by SAS version that has been truncated to the first 9 characters so that incremental hot fixes do not impact the program. Slowly changing dimensions (SCD) are used via the effective begin and end dates to retain the history. The actual code is shown below.

data mylib.lookup;
  infile datalines dsd dlm = '~';
  attrib
    pk             length = 5
    version        length = $16
    eff_begin_date length = 4 format = date9. informat = date9.
    eff_end_date   length = 4 format = date9. informat = date9.
    name           length = $128
    value          length = $256
    createdby      length = $8
    createdate     length = 4 format = date9. informat = date9.
  ;
  input (pk -- createdate) (:);
  datalines;
1~9.04.01M3~01jan2017~30dec9999~WEB~oldserver@myco.org:8343~myid~21may2020
2~9.04.01M6~01may2020~30dec9999~WEB~newserver@myco.org:8343~myid~21may2020
3~9.04.01M3~01jan2017~30dec9999~METAPORT~8562~myid~21may2020
4~9.04.01M6~01may2020~30dec9999~METAPORT~8561~myid~21may2020
run;

/******************************************************************************* Program: lookup.sas Author: Tom Bellmer Created: 05/21/2020 @ 1:46:19 PM SAS Version: SAS 9.4 (TS1M3) OS: LIN X64 Purpose: Macro function to return value from a lookup name. Uses slowly changing dimension to support changes within a version Usage: %let port = %lookup(metaport); Notes: version is truncated to first nine characters to avoid hotfix changes Modifications in descending order FL-YYYYMMDD Description ----------- -------------------------------------------------------------------- 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0 *******************************************************************************/ %macro lookup(name); %local dsid rc retval; %let dsid = %sysfunc( open( mylib.lookup( where = ( "%substr(&sysvlong, 1, 9)" = version and %sysfunc(date()) >= eff_begin_date and %sysfunc(date()) <= eff_end_date and "%upcase(&name)" = upcase(name) ) ) ) ); %if &dsid. = 0 %then %put %sysfunc(sysmsg()); %else %do; %if %sysfunc(fetch(&dsid)) = 0 %then %let retval = %sysfunc(getvarc(&dsid, %sysfunc(varnum(&dsid., value)))); %else %put %str(E)RROR: no entry found for name = &name..; %let dsid = %sysfunc(close(&dsid)); %end; &retval. %mend; /*EOF: lookup.sas */