Tip: Macro to Describe SAS 9.1 Views from SAS 9.3 (Linux)

Follow

Overview

During a recent SAS migration exercise to SAS 9.3 on Linux we were faced with hundreds of SAS Data Step Views that were created in SAS 9.1. Because the Views did not have their source code saved when they were originally created, we were faced with having to start up the previous version of SAS and describe each view. Then we could re-run that code to re-create the view in 9.3.

Describing a SAS 9.1 view without leaving SAS 9.3

As inferred in the above overview, this method and code were created to solve a specific problem on Linux - although it may be possible to modify the code to run on another operating system.  Due to the large number of Views, and the volume of "black box" code that was being run, it was difficult to identify before-hand which Views needed to be updated. When some code referenced an old View, the following ERROR would appear:

WARNING: File MART.SALES_VIEW.VIEW was created for a different operating system.

ERROR: The view MART.SALES_VIEW was created on an incompatible host and cannot execute on this host.

The macro we created allows us to stay in SAS 9.3 (in our case via Enterprise Guide) to describe the older view as we come across it by issuing the following macro call:

%describe_view(VIEW_LIBRARY=mart, VIEW_NAME=sales_view);

This call would output the following lines to the SAS log:

********************************************************************************
* View: sales_view                                                             *
* Location: /data/production/datamart
********************************************************************************
* Libname statement:                                                           *;
* LIBNAME mart '/data/production/datamart';
********************************************************************************;
data mart.sales_view / view= mart.sales_view;
   merge mart.sales_fact(in=a where=(today()-30 le sales_date le today()))
         mart.customer(in=b);
   by customer_id;
   if a and b;
run;

The SAS user can then take the provided code and run it in SAS 9.3 to create the new view in SAS 9.3.

The macro takes the following three parameters:

Parameter Description Notes
VIEW_LIBRARY

The LIBREF containing the View (as allocated in the current 9.3 session)
OR
The absolute path to the directory containing the View

Required

VIEW_NAME The name of the View Required
SAS_BIN The absolute path to the older SAS binary, e.g. /usr/local/SAS_9.1/sas Optional

Macro Code

%macro DESCRIBE_VIEW(
  VIEW_LIBRARY= /* The LIBREF or absolute path containing the view */
 ,VIEW_NAME= /* The name of the view to describe */
 ,SAS_BIN=%str(/usr/local/SAS/SAS_9.1/sas) /* The full path to the SAS binary */
 );
  %* Web know our quoted strings are going to be very long, so dont warn us;
  %let _OPTQLM=%sysfunc(getoption(QUOTELENMAX));
  %let _OPTNOTES=%sysfunc(getoption(NOTES));
  %let _OPTSOURCE=%sysfunc(getoption(SOURCE));
  options noquotelenmax nonotes nosource;
  %* VIEW_LIBRARY can be a LIBREF of an absolute path - work out which was used;
  %if %quote(%substr(%str(&VIEW_LIBRARY),1,1)) NE %quote(/) %then %do;
    %* Libref was passed in;
  %if %sysfunc(libref(&VIEW_LIBRARY)) = 1 %then %do;
    %* A LIBREF was used but it isnt allocated;
    %put ERROR: Library &VIEW_LIBRARY has not been allocated.;
    %return;
  %end;
  %else %do;
    %* A LIBREF was used - get the physical file path;
    %let _VIEW_LIBRARY=%sysfunc(pathname(&VIEW_LIBRARY));
  %end;  
  %end;
  %else %do;
    %* An absolute path was used, so just take it as-is;
    %let _VIEW_LIBRARY=%str(&VIEW_LIBRARY);
  %end;
  %let _VIEW_NAME=%str(&VIEW_NAME);
  %let cmd=%str(%')cd "$HOME" %nrstr(&&) env -i HOME="$HOME" PATH=$PATH &SAS_BIN -nonotes -nosource -initstmt "proc printto log=stdout%str(;)run%str(;)data view=v.&_VIEW_NAME.%str(;)describe%str(;)run%str(;)" -set V &_VIEW_LIBRARY. -sysin /dev/null -log /dev/null%str(%');
  filename cmd pipe %unquote(&CMD);
  data _null_;
    infile cmd;
    input;
    if _N_=1 then do;
    a=repeat('*',79);
    length libref $ 8;
    libref=scan(_infile_,2," .");
    put / a;
    put "* View: &_VIEW_NAME" @80 "*";
    put "* Location: &_VIEW_LIBRARY";
    put a;
    put '* Libname statement:' @80 '*;';
    put "* LIBNAME " libref "'&_VIEW_LIBRARY';";
    put a +(-1)";";
  end;
    put _infile_;
  run;
  filename cmd clear;
  options &_OPTQLM &_OPTNOTES &_OPTSOURCE;
%mend; 
Sample files and code examples are provided by Scorpio Software Services "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. Recipients acknowledge and agree that Scorpio Software Services shall not be liable for any damages whatsoever arising out of their use of this material.
Was this article helpful?
0 out of 0 found this helpful

Comments

Powered by Zendesk