MainframeSupports
tip uge 25/2015:

Jeg har i mange år undladt at skrive et tip om at eksekvere SQL mod DB2 fra REXX, selv om jeg har gjort det rigtig meget. Det skyldes, at der findes et hav af forskellige varianter af REXX interfaces til DB2. På et tidspunkt kom IBM også ind i kampen og lavede deres interface DSNREXX, som kan bruges på alle installationer. Desværre er DSNREXX ikke i nærheden af at være et lige så godt interface som nogle af de andre, jeg har arbejdet med. Men nu kan jeg i det mindste skrive et tip om at kalde SQL mod DB2 fra REXX, som bør virke på alle installationer (med mindre DB2 systemprogrammøren med vilje har valgt det fra).

Jeg vil lidt usædvanligt dele tippet op over to tip, og starte med det simple tip, nemlig hvordan du eksekverer et SQL statement, der ikke er en SELECT. Der er nemlig rigtig stor forskel i kompleksiteten. Og her kommer så et eksempel:

/* REXX */
SUBCOM DSNREXX
IF RC THEN X=RXSUBCOM('ADD','DSNREXX','DSNREXX')
CALL SQLEXEC 0, "CONNECT MYDB"
CALL SQLEXEC 0, "EXECSQL SET CURRENT PACKAGESET='DSNREXCS'"

SQLSTMT="INSERT INTO MYUSER.MYSYSTABLES SELECT * FROM SYSIBM.SYSTABLES",
        " WHERE CREATOR = 'SYSIBM'"
CALL SQLEXEC 0, "EXECSQL "SQLSTMT

CALL SQLEXEC 0, "EXECSQL COMMIT"
CALL SQLEXEC 0, "DISCONNECT"
RC=RXSUBCOM('DELETE','DSNREXX','DSNREXX')
EXIT

SQLEXEC:
  ARG ACCEPT, STMT
  ADDRESS DSNREXX STMT
  IF SQLCODE <> 0 & SQLCODE <> ACCEPT
  THEN
    IF WORD(STMT,1) = 'EXECSQL'
    THEN
      SAY WORD(STMT,2)': SQLCODE='SQLCODE
    ELSE
      SAY WORD(STMT,1)': SQLCODE='SQLCODE
  ELSE
    SAY STMT
RETURN

Denne REXX består af selve programmet og en procedure til at kalde DSNREXX interfacet. Denne opsplitning gør det meget nemmere at fejlhåndtere og selve progammet bliver langt lettere at læse. Til gengæld egner opsplitningen sig ikke til at eksekvere mange SQL kald med, da proceduren SQLEXEC er tung at kalde.

Allerførst skal REXX interfacet til DB2 gøres kendt for REXX. Det sker med de to første statements i selve programmet. Dernæst skal programmet lave en connect til den DB2, der skal udføre de ønskede SQL statements. I eksemplet hedder DB2 systemet MYDB. Det kan du erstatte med navnet på din DB2 eller med en variabel, så du kan gøre dit program uafhængigt af DB2 system. Den sidste detalje, før din REXX er klar til at udføre dit SQL kald, er SET CURRENT PACKAGESET. Så vidt jeg kan lure, så er dette kald ikke strengt nødvendigt, det afhænger lidt af, hvordan man på din installation har valgt at implementere DSNREXX interfacet. Her kan du prøve dig frem.

Så er vi endelig klar til at udføre et SQL statement. Som sagt kan denne REXX klare alt undtagen SELECT statements. Jeg har lavet en tabel kaldet MYUSER.SYSTABLES, som er magen til SYSIBM.SYSTABLES, og den kopierer jeg lige samtlige rækker med creator SYSIBM fra SYSIBM.SYSTABLES over i. Du kan næsten assigne SQLSTMT et hvilket som helst dynamisk SQL statement (bortset fra SELECT) og få det udført. Jeg skriver næsten, fordi der findes enkelte undtagelser, som du kan læse om i Application programming and SQL Guide.

Når programmet er færdigt med at udføre SQL statements, så er det en god ide at udstede en COMMIT, selv om det ikke er krævet. Der skal under alle omstændigheder laves en disconnect fra DB2 og til allersidst fjernes programmets relation til DSNREXX interfacet. Så er der pænt ryddet op. Du kan efter en disconnect sagtens lave en ny connect til en anden DB2 og så udføre SQL statements mod denne DB2. Det giver langt større fleksibilitet end du normalt kan få med COBOL eller PLI.

Forrige danske tip        Last tip in english        Tip oversigten