DICTIONARY.COLUMNS geht auch schnell

Aus BI-Snippets - Business Intelligence Code und Module
Wechseln zu: Navigation, Suche

Wer viel mit dem SAS-Dictionary arbeitet hat sicherlich die nicht gerade überagende Performance feststellen können. Wenn viel auf das Dictionary zugegriffen wird, kann sich dies schnell als Bremse bemerkbar machen.

Dieses kleine Makro erstellt in der Bibliothek WORK in wenigen Millisekunden eine Tabelle, die die wesentlichen Attribute aus dem Spalten-Dictionary nachbildet.

Bestehende Abfragen auf das Dictionary können problemlos umgestellt werden. Vor der Abfrage u.a. Makro für die gewünschte Tabelle aufrufen und anschließend in der Abfrage auf das Dictionary DICTIONARY.COLUMNS durch DICTIONARY_COLUMNS ersetzen. <syntaxhighlight lang="SAS" line="1" >%macro create_dictionary_columns(lib, tabelle);

 %if %sysfunc(exist(work.DICTIONARY_COLUMNS)) %then %do;
   proc sql threads noprint;
     delete from work.DICTIONARY_COLUMNS where libname eq "%upcase(&lib)" and memname eq "%upcase(&tabelle)";
   quit;
 %end;
 %if %sysfunc(exist(&lib..&tabelle)) or %sysfunc(exist(&lib..&tabelle, VIEW)) %then %do;
   proc contents data=&lib..&tabelle out=work._DICTIONARY noprint;
   run;
   %if %sysfunc(exist(work.DICTIONARY_COLUMNS)) %then %do;
     data work.DICTIONARY;
   %end; %else %do;
     data work.DICTIONARY_COLUMNS;
   %end;
       format type $4.;
       set work._DICTIONARY(keep=formatl formatd libname memname name format length type rename=(type=type_num));
       drop type_num formatl formatd;
       name=upcase(name);
       memname=upcase(memname);
       libname=upcase(libname);
       if type_num eq 1 then do;
         type='num';
         if formatl eq 0 then do;
           if strip(format) eq  then do;
             format = 'BEST12.';
           end; else do;
             format = strip(format) || '12.';
           end;
         end; else do;
           format = strip(format) || strip(put(formatl, 15.)) || '.';
         end;
         if formatd ne 0 then format = strip(format) || strip(put(formatd, 15.));
       end; else do;
         type='char';
         if formatl eq 0 and strip(format) ne '$' then do;
           format = '$' || strip(put(length, 15.)) || '.';
         end; else do;
           format = strip(format) || strip(put(formatl, 15.)) || '.';
         end;
       end;
     run;
     proc sql noprint;
       drop table work._DICTIONARY;
     quit;
   %if %sysfunc(exist(work.DICTIONARY)) %then %do;
     proc append base=work.DICTIONARY_COLUMNS data=work.DICTIONARY;
     run;
     proc sql threads noprint;
       drop table work.DICTIONARY;
     quit;
   %end;
 %end;

%mend;</syntaxhighlight>