Aktualności i artykuły

Opublikowano: 23 marca 2016
Kategoria wpisu: administracjaporadnikiprogramowanie

Porównanie zawartości bibliotek

Aby szybko porównać zawartość dwóch bibliotek na serwerze AS/400 wystarczy kilka komend CL i znajomość Query lub SQL’a. Ale gdy do porównania jest kilkadziesiÄ…t bibliotek to warto zastanowić siÄ™ nad stworzeniem prostego narzÄ™dzia które wykona tÄ… pracÄ™ za nas, a czas poÅ›wiÄ™cony na jego stworzenie nie bÄ™dzie wiele dÅ‚uższy niż „rÄ™czne” wykonywanie tego zadania.

Stając ostatnio przed takim zadaniem postanowiłem stworzyć komendę, która po podaniu nazw dwóch bibliotek porówna ich zawartość i zwróci wynik w postaci listy obiektów które są w jednej z bibliotek, a nie ma ich w drugiej. Rzecz dotyczyła porównania plików ekranowych i wydrukowych (tak zwanych display files i printer files), ale dodając możliwość wyboru typu obiektu oraz jego atrybutu, komenda staje się bardziej uniwersalna i tak została przygotowana.

NarzÄ™dzie jest proste, pozwala na podanie dwóch nazw bibliotek oraz ewentualnie typu porównywanych obiektów – domyÅ›lnie brane sÄ… pod uwagÄ™ wszystkie obiekty w bibliotece. Komenda sÅ‚użąca do uruchomienia funkcji może wyglÄ…dać nastÄ™pujÄ…co:

CMD        PROMPT('Library compare')                   
                                                       
PARM       KWD(LIBFROM) TYPE(*CHAR) LEN(10) RSTD(*NO) +
             CHOICE('Name, *LIBL') +                   
             PROMPT('Source library')                  
PARM       KWD(LIBTO) TYPE(*CHAR) LEN(10) RSTD(*NO) +  
             CHOICE('Name, *LIBL') +                   
             PROMPT('Destination library')             
PARM       KWD(OBJTYPE) TYPE(*CHAR) LEN(10) RSTD(*NO) +
             DFT(*ALL) CHOICE('*ALL, *type') +         
             PROMPT('Object type')                     
PARM       KWD(OBJATTR) TYPE(*CHAR) LEN(10) RSTD(*NO) +
             DFT(*ALL) CHOICE('*ALL, attribute') +     
             PROMPT('Object attribute')               

Program w języku CL, który zrealizuje opisaną funkcjonalność działa następująco:

  • na podstawie parametrów wejÅ›ciowych przekazanych z komendy, tworzone sÄ… w bibliotece QTEMP pliki robocze ze spisem obiektów w każdej z bibliotek;
/* pliki robocze ze spisem obiektów z obu bibliotek */       
DSPOBJD    OBJ(&LIBFROM/*ALL) OBJTYPE(&OBJTYPE) +         
           OUTPUT(*OUTFILE) OUTFILE(QTEMP/&LIBFROM)     
MONMSG     MSGID(CPF2123) EXEC(GOTO CMDLBL(ERRFIN))      
  • nastÄ™pnie tworzona jest kwerenda w jÄ™zyku SQL która na podstawie zawartoÅ›ci obu zbiorów wybierze te obiekty, które sÄ… w bibliotece źródÅ‚owej a nie  ma ich w bibliotece docelowej i utworzy z nich zbiór bazy danych; przy tworzeniu zapytania korzystam z LEFT OUTER JOIN którego sposób dziaÅ‚ania Å›wietnie wyjaÅ›nia poradnik ”A Visual Explanation of SQL Join”;
/* parametr z kwerendą SQL - LEFT OUTER JOIN */            
CHGVAR     VAR(&PARM1) VALUE('create table QTEMP/CMPLIBS +
           as (select ' *CAT &LIBFROM *TCAT +           
           '.ODOBNM, ' *CAT &LIBFROM *TCAT '.ODOBTP, +  
           ' *CAT &LIBFROM *TCAT '.ODOBAT from +        
           QTEMP/' *CAT &LIBFROM *TCAT ' left outer +   
           join QTEMP/' *CAT &LIBTO *CAT ' on ' *CAT +  
           &LIBFROM *TCAT '.ODOBNM = ' *CAT &LIBTO +    
           *TCAT '.ODOBNM and ' *CAT &LIBFROM *TCAT +   
           '.ODOBTP = ' *CAT &LIBTO *TCAT '.ODOBTP +    
           where ' *CAT &LIBTO *TCAT '.ODOBNM is +      
           null and ' *CAT &LIBTO *TCAT '.ODOBTP is +   
           null ' *CAT +                                
           &PARM2 *TCAT &PARM3 *TCAT ' ) with data')   
  • jeÅ›li na ekranie komendy wprowadzony zostaÅ‚ typ wybieranych obiektów i atrybut, do zapytania doÅ‚Ä…czany jest odpowiedni fragment;
/* parametr z fragmentem kwerendy SQL dotyczącej wyboru typu obiektu */    
IF         COND(&OBJTYPE *NE '*ALL') THEN(CHGVAR +               
           VAR(&PARM2) VALUE(' and ' *CAT &LIBFROM +           
           *TCAT '.ODOBTP =' *CAT '''' *CAT &OBJTYPE +         
           *TCAT ''''))                                        
/* parametr z fragmentem kwerendy SQL dotyczÄ…cej wyboru atrybutu obiektu */
IF         COND(&OBJATR *NE '*ALL') THEN(CHGVAR +                
           VAR(&PARM3) VALUE(' and ' *CAT &LIBFROM +           
           *TCAT '.ODOBAT =' *CAT '''' *CAT &OBJATR +          
           *TCAT ''''))                                       
  • nastÄ™pnie wystarczy uruchomić utworzone zapytanie – mechanizm i możliwość wykorzystania komendy RUNSQL opisany jest w jednym ze starszych wpisów – i wynik przesÅ‚ać na wyjÅ›cie – do moich potrzeb wystarczyÅ‚a prezentacja na ekranie;
/* uruchomienie kwerendy SQL */                             
RUNSQL     SQL(&PARM1) COMMIT(*NONE) NAMING(*SYS)
MONMSG     MSGID(SQL9010)                         
/* prezentacja wyników na ekranie za pomocą RUNQRY */       
RUNQRY     QRYFILE((QTEMP/CMPLIBS))             

Ten przykład może być dowodem na to, że w szybki i prosty sposób można tworzyć własne narzędzia i komendy do automatyzacji czynności wykonywanych na co dzień.

Komendę wraz z programem CL i źródłami można pobrać tutaj:

  CMPLIBS (643,5 KiB, 841 hits)

^