Hvis du nogensinde har brugt REXX til at udstede DB2-kommandoer med, så kender du sandsynligvis til de underlige problemer og fejlmeldinger, der opstår, hvis kaldet til DSN-kommandoen fejler. Det kan skyldes noget så simpelt som, at subsystemets navn er forkert angivet.
Jeg har i rigtig mange år ignoreret at gøre noget ved disse fejlmeldinger. Hvis det har været kritisk for min REXX har jeg brugt en CLIST i stedet (ja du læste rigtigt), men her for nyligt blev jeg grebet af den hellige ild og besluttede, at nu skulle det være slut. Ud med CLIST og ind med ren REXX programmering.
De mærkelig fejlmeldinger skyldes, at interfacet mellem REXX og DSN benytter REXXs indbyggede stak. Hvis stakken ikke er tømt, når ens REXX terminerer, så vil de resterende data på stakken blive sendt til eksekvering i TSO. De fleste kommandoer, som DSN forstår, kender TSO ikke, og så svarer TSO med fejlmeldinger, men det virker jo som om disse kommer fra REXX'en. Løsningen er at tømme REXX stakken inden REXX-progammet afsluttes. Jeg har lavet et lille eksempel, der udsteder en -DIS UTIL(*) og udskriver resultatet:
/* REXX DISUTIL */ ARG SSID PUSH "END" PUSH "-DIS UTIL(*)" CALL MSG('ON') CALL OUTTRAP('COMMAND.') ADDRESS TSO "DSN SYSTEM("SSID")" CALL OUTTRAP('OFF') CALL MSG('OFF') DO LINENO = 1 TO COMMAND.0 SAY COMMAND.LINENO END DO LINENO = 1 TO QUEUED() PULL END EXIT
Hvis du kalder REXX'en DISUTIL, så kalder du den med TSO %DISUTIL DB2A hvis dit subsystem hedder DB2A. Først skal du fortælle REXX stakken, hvad den sidste kommando, der skal udføres af DSN hedder. Derfor starter REXX'en med at lave PUSH "END". Herefter kommer den næstsidste kommando og så fremdeles. Når alt er lagt på stakken, så kaldes DSN. For at fange outputtet benytter jeg OUTTRAP. Så udskriver jeg outputtet med SAY. Den sidste DO løkke fjerner eventuelle rester af data, der stadig ligger og flyder på stakken.
Hvis nu DB2A ikke findes på den MVS, hvor du udsteder kommandoen, så vil DSN kommandoen fejle. Jeg har udeladt fejlbehandlingen her for at illustrere, at man kan klare sig uden, selv om det ikke er særligt informativt. Når DSN fejler, så vil OUTTRAP ikke fange noget, og så vil COMMAND.0 være 0. Til gengæld vil QUEUED() returnere et tal større end 0 og dermed vil løkken fjerne de kommandoer til DSN, der ikke blev behandlet. Herefter vil REXX'en terminere normalt uden sjove fejlbeskeder.