REXX procedure for DPropR Apply V5 Information and Control
This TSO/E REXX procedures reads information from Data Propagator tables, which can be used to control dependent process flow.
The procedure is quite old but still a good sample for querying Data Propagator Control Tables.
/*REXX****************************************************************/ /* APPLYIS....: DPropR Apply V5 Information and Control */ /*-------------------------------------------------------------------*/ /* CALLED BY..: IKJEFT01 - TSO online or batch */ /* ARGUMENTS..: SSID I - DB2 Subsystem ID */ /* ASNQUAL I - Apply Qualifier and opt. SET name */ /* OPTION I - SUBS list subscriptions */ /* I - TRAIL list log (APPLYTRAIL) */ /* I - CHECK check sub's success */ /* I - WATCH watch sub's processing for n secs */ /* I - MAINT deletes from APPLYTRAIL */ /* I - ACT activate subscriptions */ /* I - DEACT deactivate subscriptions */ /* I - EVENT add an event timestamp */ /* CALLS......: RXSQL M - REXX to SQL Interface */ /* D2PABND M - batch only: abend job step */ /* anyWAIT M - platform standard WAIT program */ /* SEND C - TSO SEND command */ /* FILES......: SYSTSPRT O - Information */ /*-------------------------------------------------------------------*/ /* FUNCTION...: This TSO/E REXX procedures reads information from */ /* Data Propagator tables, which can be used to */ /* control dependent process flow. */ /*-------------------------------------------------------------------*/ /* COMMENTS...: Remind, when comparing LASTRUN and LASTSUCCESS, that */ /* Apply does not set microseconds in LASTSUCCESS. */ /*-------------------------------------------------------------------*/ /* HISTORY....: 29.09.98/GR - V1R0 Gernot Ruban */ /* 98-10-09/GR: IWWTO replaced by TSO SEND to CN(00), V1.1 */ /* anyWAIT instead of timer function, */ /* tolerance for WATCH functions, new functions ACT, */ /* DEACT and EVENT. MAINT expanded for events. */ /* 98-10-19/GR: WAIT-Select corrected V1.1 */ /* 98-12-02/GR: SYNCHRONIZE and opt. parm setname added V1.2 */ /* 99-01-12/GR: STOP added, new parms for MAINT and EVENT V1.3 */ /* 99-01-20/GR: problem with event time fixed, new parameter V1.4 */ /* EVENT RESTART added */ /*********************************************************************/ x = MSG("OFF") /********************************************************************/ /* Initial values */ /********************************************************************/ version = "V1.4"; /* Current version */ tolerance = "2 HOURS"; /* Set watching time tolerance default value */ /********************************************************************/ /* Check arguments passed */ /********************************************************************/ parse upper arg ssid "," asnqual "," option "," debug If ssid = "", ! ( option <> "SUBS" , & option <> "TRAIL" , & option <> "CHECK" , & pos("WATCH",option) = 0, & pos("MAINT",option) = 0, & pos("EVENT",option) = 0, & option <> "ACT" , & option <> "DEACT" , & option <> "SYNCH" , & option <> "STOP" , & option <> "" ) then signal syntax if pos("WATCH",option) > 0 then do if words(option) > 1 then do wtime = word(option,2) if words(option) > 2 then tolerance = subword(option,3) option = "WATCH" if verify(wtime,"0123456789") > 0 then signal syntax end else wtime = 60 /* dflt watch time in minutes */ end if pos("MAINT",option) > 0 then do if words(option) > 1 then mtime = subword(option,2) else mtime = "" option = "MAINT" end if pos("EVENT",option) > 0 then do if words(option) > 1 then do etime = word(option,2) option = "EVENT" if etime <> "RESTART", & verify(etime,"0123456789") > 0 then signal syntax end else etime = "" /* dflt event time */ end if debug = "DEBUG" then trace ?I /********************************************************************/ /* Write header to report file */ /********************************************************************/ say copies("#",79) say "# APPLYIS - DPropR Apply V5 Info System "version" "left(ssid,4), " "date("O")" "time()" #"; say copies("#",79) /********************************************************************/ /* Set RXSQL's thread type: NO EXPLICIT SQL END (single thread) */ /********************************************************************/ rxsql_db2cleanup = "NOSQLEND" /********************************************************************/ /* Apply qualifier containing search pattern results in SQL LIKE */ /********************************************************************/ parse value asnqual with asnqual"."setname if pos("%",asnqual) > 0 , ! pos("_",asnqual) > 0 then pred_qual = "APPLY_QUAL LIKE '"asnqual"%'" else pred_qual = "APPLY_QUAL = '"asnqual"'" /********************************************************************/ /* Check SET_NAME */ /********************************************************************/ if setname <> "" then do if pos("%",setname) > 0 , ! pos("_",setname) > 0 then set_qual = "SET_NAME LIKE '"setname"%'" else set_qual = "SET_NAME = '"setname"'" end else set_qual = "SET_NAME >= ''" /********************************************************************/ /* Distinguish between options */ /********************************************************************/ select when option = "SUBS" then CALL LIST_SUBS when option = "TRAIL" then CALL LIST_TRAIL when option = "CHECK" then CALL CHECK_SUBS when option = "WATCH" then CALL WATCH_SUBS when option = "MAINT" then CALL MAINT_TRAIL when option = "ACT" then CALL MODIFY_SUBS "ACT" when option = "DEACT" then CALL MODIFY_SUBS "DEACT" when option = "EVENT" then CALL ADD_EVENT when option = "SYNCH" then CALL SYNCHRONIZE when option = "STOP" then CALL STOP_TASK otherwise CALL LIST_SUBS end say "" say "APPLYIS: ends with CC=0" exit 0 /********************************************************************/ /* */ /* Internal subprocedures and functions */ /* */ /********************************************************************/ /********************************************************************/ /* SYNCHRONIZE: Move ASN.IBMSNAP_REGISTER.CD_OLD_SYNCHPOINT */ /* to ASN.IBMSNAP_SUBS_SET.SYNCHPOINT */ /* */ /* This is to avoid gaps for noncomplete target tables */ /********************************************************************/ SYNCHRONIZE: CALL LIST_SUBS stmt = "SELECT DISTINCT SOURCE_SERVER, ", "SOURCE_OWNER, SOURCE_TABLE", "FROM ASN.IBMSNAP_SUBS_SET S,", " ASN.IBMSNAP_SUBS_MEMBR M", "WHERE S."pred_qual, "AND S."set_qual, "AND S.APPLY_QUAL = M.APPLY_QUAL", "AND S.SET_NAME = M.SET_NAME"; cc = DOSQL(stmt) say " " say "LIST OF SYNCHRONIZED SUBS SET MEMBERS: "rxsql_0" list entries" say "======================================" do i=1 to rxsql_0 stmt = "SELECT MAX(CD_OLD_SYNCHPOINT)", "FROM "space(source_server.i)".ASN.IBMSNAP_REGISTER R,", space(source_server.i)".ASN.IBMSNAP_PRUNCNTL P", "WHERE P."pred_qual, "AND P."set_qual, "AND P.SOURCE_OWNER = '"source_owner.i"'", "AND P.SOURCE_TABLE = '"source_table.i"'", "AND P.SOURCE_OWNER = R.SOURCE_OWNER", "AND P.SOURCE_TABLE = R.SOURCE_TABLE"; cc = DOSQL(stmt) if cc = 0 then do stmt = "UPDATE ASN.IBMSNAP_SUBS_SET", "SET SYNCHPOINT = '"temp.1.1"'", "WHERE "pred_qual, "AND "set_qual; cc = DOSQL(stmt) if cc = 0 then say left(source_owner.1,18)" ! "left(source_table.i,18), "synchronization successful."; else say left(source_owner.1,18)" ! "left(source_table.i,18), "synchronization failed."; end end return /********************************************************************/ /* WATCH_SUBS: Watch DPropR Apply Subscription processing for */ /* specified number of seconds, abend if elapsed or */ /* unsuccessful subscriptions found. */ /* List Success of Subscriptions, */ /* Abend Procedure if unsuccessful subscriptions */ /********************************************************************/ WATCH_SUBS: CALL LIST_SUBS say " " say copies("=",79) say "= START WATCHING EXECUTING SUBSCRIPTIONS:"copies(' ',37)"=" say copies("=",79) say "Apply Qualifier .............: "asnqual say "Wait for Apply to finish work: "wtime" minutes" stmt = "SELECT CURRENT TIMESTAMP, CURRENT TIMESTAMP - " tolerance, "FROM SYSIBM.SYSDUMMY1"; cc = DOSQL(stmt) ctim = temp.1.1 ftim = temp.2.1 say "Current DB2 Timestamp .......: "ctim say "Tolerance ...................: "tolerance say "Watch Time Frame ............: "ftim drop temp.1.1 temp.2.1 /*****************************************************************/ /* Check subscriptions sets until successful or wait time elapsed*/ /*****************************************************************/ wexec = 0 wwait = time("R") /* timer reset */ do while wexec = 0 & wwait <= wtime*60 stmt = "SELECT VALUE(COUNT(*),0)", "FROM ASN.IBMSNAP_SUBS_SET", "WHERE "pred_qual, "AND LASTRUN > '"ftim"'", "AND ACTIVATE > 0", "AND STATUS = 0", "HAVING COUNT(*) = (", "SELECT COUNT(*)", "FROM ASN.IBMSNAP_SUBS_SET", "WHERE "pred_qual, "AND ACTIVATE > 0 )"; /**"AND LASTRUN > '"ftim"'", 98/10/19/GR**/ cc = DOSQL(stmt) /**************************************************************/ /* No result: not run, not completely finished or deactivated */ /* Result : all subscriptions processed */ /**************************************************************/ if rxsql_0 > 0, & temp.1.1 > 0 then do wexec = 1 say time()": "space(temp.1.1)" subscriptions processed." end else do say time()": Apply did not process all subscriptions till now." /*********************************************************/ /* Wait a while (handle minutes as secs), at least 1 min */ /*********************************************************/ parm = "'"max(wtime,60)"'" ADDRESS TSO "CALL *(anyWAIT) " PARM /*CALL WAIT WTIME*/ end wwait = time("E") /* elapsed time */ end /*****************************************************************/ /* Wait time exceeded or subscriptions finished: */ /* Check success of subscriptions, issue WTO message */ /*****************************************************************/ CALL CHECK_SUBS "WATCH" "WTO YES" return /********************************************************************/ /* STOP_APPLY: Stop or cancel Apply Job */ /********************************************************************/ STOP_APPLY: Procedure arg job /*****************************************************************/ /* Job exists and is executing */ /*****************************************************************/ x = msg("ON") x = outtrap("line.","*") address TSO "STATUS "job cc = rc x = outtrap("OFF") x = msg("OFF") found = 0 do i=1 to line.0 if pos("EXECUTING",line.i) then do found = 1 j=pos("(",line.i) k=pos(")",line.i) if j>0 &k>0 then jobid = substr(line.i,j+1,k-j-1) else jobid = '' end end if found = 0 then do say " " say "APPLYIS: DPropR Apply job "job" is not executing - cannot cancel!" say " Current status: "line.1 do i=2 to line.0 say " "line.i end return end /*****************************************************************/ /* Cancel Job */ /*****************************************************************/ if jobid = "" then address TSO "CANCEL "job else address TSO "CANCEL "job"("jobid")" say " " say "APPLYIS: Cancel "job" ended with RC="rc return /********************************************************************/ /* WAIT: Wait a specified time of seconds */ /********************************************************************/ WAIT: Procedure arg secs s = time("R") s = time("R") do while s<secs s = time("E") end s = time("R") return /********************************************************************/ /* CHECK_SUBS: Check DPropR Apply Subscription sets */ /********************************************************************/ CHECK_SUBS: arg mode wto /*****************************************************************/ /* Mode WATCH issues query on APPLY_TRAIL - tolerance */ /* (tolerance already computed in preceeding procedure) */ /*****************************************************************/ if mode = "WATCH" then do add_predicate = "AND B.LASTRUN >= '"ftim"'" add_predicate2 = "OR B.LASTRUN < '"ftim"'" end else do add_predicate = "" add_predicate2 = "" end /*****************************************************************/ /* Successful Subscriptions */ /*****************************************************************/ unsucc = 0 running = 0 stmt = "SELECT B.APPLY_QUAL, B.SET_NAME, B.LASTRUN", "FROM ASN.IBMSNAP_SUBS_SET A,", " ASN.IBMSNAP_APPLYTRAIL B", "WHERE A."pred_qual, "AND A.APPLY_QUAL = B.APPLY_QUAL", "AND A.SET_NAME = B.SET_NAME", "AND A.LASTRUN = B.LASTRUN", "AND A.STATUS = 0", add_predicate, "AND SUBSTR(CHAR(A.LASTRUN),1,19) = ", " SUBSTR(CHAR(A.LASTSUCCESS),1,19)", "AND ( B.SQLCODE IS NULL", " OR ( B.SQLCODE IS NOT NULL", " AND B.SQLCODE IN (0,100) ) )", "ORDER BY 1 , 2 , 3"; cc = DOSQL(stmt) say " " say "LIST OF SUCC. PROCESSED SUBSCRIPTION SETS: "rxsql_0" list entries" say "==========================================" if mode = "WATCH" then say "(Must have execution end time after "ftim".)" /*****************************************************************/ /* Process all result rows */ /*****************************************************************/ say "Apply Qualifier !Set Name !Last Run " say "------------------+------------------+--------------------------" do i=1 to rxsql_0 say left(b.apply_qual.i,18)"!" !!, left(b.set_name.i,18)"!" !!, b.lastrun.i end /*****************************************************************/ /* Unsuccessful subscriptions */ /*****************************************************************/ stmt = "SELECT B.APPLY_QUAL, B.SET_NAME, B.LASTRUN, ", " B.SQLCODE*1, B.LASTSUCCESS, B.SQLSTATE", "FROM ASN.IBMSNAP_SUBS_SET A,", " ASN.IBMSNAP_APPLYTRAIL B", "WHERE A."pred_qual, "AND A.APPLY_QUAL = B.APPLY_QUAL", "AND A.SET_NAME = B.SET_NAME", "AND A.LASTRUN = B.LASTRUN", "AND ( ( B.SQLCODE IS NOT NULL", " AND B.SQLCODE NOT IN (0,100) )", add_predicate2, " OR (SUBSTR(CHAR(A.LASTRUN),1,19) <> ", " SUBSTR(CHAR(A.LASTSUCCESS),1,19) ) )", "ORDER BY 1 , 2 , 3"; cc = DOSQL(stmt) say " " say "LIST OF UNSUCC. PROCESSED SUBSCRIPTION SETS: "rxsql_0" list entries" say "============================================" /*****************************************************************/ /* Process all result rows */ /*****************************************************************/ say "Apply Qualifier !Set Name !Last Run / Last Success !SQLCODE" say "------------------+------------------+--------------------------+-------" do i=1 to rxsql_0 unsucc = 1 say left(b.apply_qual.i,18)"!" !!, left(b.set_name.i,18)"!" !!, left(b.lastrun.i,26)"!"!!, temp.1.i if mode = "WATCH", & space(b.lastsuccess) < ftim, & ( space(temp.1.i) = "", ! space(temp.1.i) = 0, ! space(temp.1.i) = 100) then say left(" ",18)"!" !!, left(" ",18)"!" !!, left(b.lastsuccess.i,26)"!"!!, "outside" else say left(" ",18)"!" !!, left(" ",18)"!" !!, left(b.lastsuccess.i,26)"!"!!, b.sqlstate.i end /*****************************************************************/ /* Subscriptions just running */ /*****************************************************************/ stmt = "SELECT A.APPLY_QUAL, A.SET_NAME, A.LASTRUN, A.ACTIVATE", "FROM ASN.IBMSNAP_SUBS_SET A", "WHERE A."pred_qual, "AND A.STATUS IN (1 , 2)", "ORDER BY 1 , 2 , 3"; cc = DOSQL(stmt) say " " say "LIST OF EXECUTING SUBSCRIPTION SETS: "rxsql_0" list entries" say "====================================" /*****************************************************************/ /* Process all result rows */ /*****************************************************************/ say "Apply Qualifier !Set Name !Last Run " say "------------------+------------------+--------------------------" do i=1 to rxsql_0 unsucc = 1 running = 1 say left(a.apply_qual.i,18)"!" !!, left(a.set_name.i,18)"!" !!, left(a.lastrun.i,26) end /*****************************************************************/ /* Subscriptions never run */ /*****************************************************************/ stmt = "SELECT A.APPLY_QUAL, A.SET_NAME, A.LASTRUN, A.ACTIVATE", "FROM ASN.IBMSNAP_SUBS_SET A", "WHERE A."pred_qual, "AND A.STATUS <> 1", "AND NOT EXISTS (SELECT 1", " FROM ASN.IBMSNAP_APPLYTRAIL", " WHERE A.APPLY_QUAL = APPLY_QUAL", " AND A.SET_NAME = SET_NAME", " AND A.LASTRUN = LASTRUN )", "ORDER BY 1 , 2 , 3"; cc = DOSQL(stmt) say " " say "LIST OF NEVER PROCESSED SUBSCRIPTION SETS: "rxsql_0" list entries" say "==========================================" /*****************************************************************/ /* Process all result rows */ /*****************************************************************/ say "Apply Qualifier !Set Name !Last Run !ACTIVE" say "------------------+------------------+--------------------------+------" do i=1 to rxsql_0 unsucc = 1 say left(a.apply_qual.i,18)"!" !!, left(a.set_name.i,18)"!" !!, left(a.lastrun.i,26)"!"!!, a.activate.i end /*****************************************************************/ /* Abend procedure whenever unsuccessful subscriptions found */ /*****************************************************************/ if unsucc = 1 then do if running = 0 then do CALL LIST_TRAIL if wto = "WTO YES" then do msg = jobname()" APPLY UNSUCCUSSFUL. STOP APPLY." ADDRESS TSO "SEND '"msg"' CN(00)" say "WTO Message issued: "msg" (RC="rc")" end say " " say "APPLYIS: Unsucessfully executed subscriptions found." signal error end else do if wto = "WTO YES" then do msg = jobname()" APPLY STILL RUNNING. STOP APPLY." ADDRESS TSO "SEND '"msg"' CN(00)" say "WTO Message issued: "msg" (RC="rc")" end say " " say "APPLYIS: Apply is still executing subscriptions." say " Increase watch time and/or check subscriptions." say " Repeat last Apply cycle to complete pending subscriptions." signal error end end else do if wto = "WTO YES" then do msg = jobname()" APPLY SUCCESSFULLY. STOP APPLY." ADDRESS TSO "SEND '"msg"' CN(00)" say "WTO Message issued: "msg" (RC="rc")" end end return /********************************************************************/ /* LIST_SUBS: List DPropR Apply Subscription sets */ /********************************************************************/ LIST_SUBS: stmt = "SELECT *", "FROM ASN.IBMSNAP_SUBS_SET", "WHERE "pred_qual, "ORDER BY APPLY_QUAL, SET_NAME"; cc = DOSQL(stmt) say " " say "LIST OF SUBSCRIPTION SETS: "rxsql_0" list entries" say "==========================" events = "" /*****************************************************************/ /* Process all result rows */ /*****************************************************************/ do i=1 to rxsql_0 say copies("-",74)!!right(i,5,"0") say "Apply Qualifier ...:"left(apply_qual.i,18), "Set Name ..........:"space(set_name.i); say "Source Server/Alias:"left(space(Source_server.i)"/"space(source_alias.i),18), "Target Server/Alias:"space(target_server.i)"/"space(target_alias.i); say "Last Run ..........:"lastrun.i say "Last Success ......:"lastsuccess.i say "Subscription active:"left(space(activate.i),5)" (0=deact 1=act 2=copy-able)" say "Status ............:"left(space(status.i),5)" (-1=failed 0=ready 1=pend 2=cont)" if refresh_timing.i = "R" then say "Refresh Timing ....:Sleep "sleep_minutes.i" minutes" if refresh_timing.i = "E" then say "Refresh Timing ....:Event "event_name.i if refresh_timing.i = "B" then say "Refresh Timing ....:Sleep "sleep_minutes.i" minutes, Event "event_name.i if space(event_name.i) <> "" then events = events"'"space(event_name.i)"'," say "Aux. Statements ...:"left(space(aux_stmts.i),5)" (# row in SUBS_STMTS)" say "Synch. Point ......:"c2x(synchpoint.i) say "Synch. Time .......:"synchtime.i end /*****************************************************************/ /* Subscription Set Members */ /*****************************************************************/ stmt = "SELECT *", "FROM ASN.IBMSNAP_SUBS_MEMBR", "WHERE "pred_qual, "ORDER BY APPLY_QUAL, SET_NAME, TARGET_OWNER, TARGET_TABLE"; cc = DOSQL(stmt) say " " say "LIST OF SUBSCRIPTION SET BASE OBJECTS: "rxsql_0" list entries" say "======================================" /*****************************************************************/ /* Process all result rows */ /*****************************************************************/ last_qual = "" last_set = "" do i=1 to rxsql_0 if last_qual <> apply_qual.i, ! last_set <> set_name.i then do say "" say copies("-",79) say "Apply Qualifier: "space(apply_qual.i), "Set Name: "space(set_name.i); say copies("-",79) say "Target Source QUAL COND COMP STRU" say "---------------------------------------------------------------------------" last_qual = apply_qual.i last_set = set_name.i end say left(space(target_owner.i)"."space(target_table.i),27), left(space(Source_owner.i)"."space(source_table.i),27), right(source_view_qual.i,3), center(target_condensed.i,4), center(target_complete.i,4), center(target_structure.i,4) end /*****************************************************************/ /* Events for Subscription Set Execution, if used */ /*****************************************************************/ if events <> "" then do events = substr(events,1,length(events)-1) CALL LIST_EVENT events end return /********************************************************************/ /* LIST_EVENT: List Subscription Events */ /********************************************************************/ LIST_EVENT: arg events stmt = "SELECT *", "FROM ASN.IBMSNAP_SUBS_EVENT", "WHERE EVENT_NAME IN ("events")", "ORDER BY EVENT_NAME, EVENT_TIME"; cc = DOSQL(stmt) say " " say "LIST OF SUBSCRIPTION EVENTS: "rxsql_0" list entries" say "============================" /************************************************************/ /* Process all result rows */ /************************************************************/ say "Event Name ! Event Time ! End of Period" say "-------------------+----------------------------+---------------------------" do i=1 to rxsql_0 say left(event_name.i,18)" !", left(event_time.i,26)" !", end_of_period.i end return /********************************************************************/ /* LIST_TRAIL: List DPropR Apply log entries */ /********************************************************************/ LIST_TRAIL: stmt = "SELECT *", "FROM ASN.IBMSNAP_APPLYTRAIL", "WHERE "pred_qual, "ORDER BY APPLY_QUAL, SET_NAME, LASTRUN DESC"; cc = DOSQL(stmt) say " " say "LIST OF LATEST APPLY LOG ENTRIES:" say "=================================" /*****************************************************************/ /* Process all result rows */ /*****************************************************************/ last_qual = "" last_set = "" j = 0 do i=1 to rxsql_0 if last_qual <> apply_qual.i, ! last_set <> set_name.i then do j = j + 1 say copies("-",74)!!right(i,5,"0") say "Apply Qualifier ...:"left(apply_qual.i,18), "Set Name ..........:"space(set_name.i); say "Last Run ..........:"lastrun.i say "Last Success ......:"lastsuccess.i say "Status ............:"space(status.i), " (-1=failed 0=ready 1=pending 2=divided)" say "ASNLOAD ...........:"left(space(asnload.i),18), "Mass Delete .......:"space(mass_delete.i); say "Inserted ..........:"left(space(set_inserted.i),18), "Reworked ..........:"space(set_reworked.i); say "Deleted ...........:"left(space(set_deleted.i),18), "Rejected TX's .....:"space(set_rejected_trxs.i); say "Updated ...........:"left(space(set_updated.i),18) if sqlcode.i <> 0, & sqlcode.i <> "" then do say "SQLSTATE/SQLCODE ..:"space(sqlstate.i)"/"space(sqlcode.i) say "SQLERRP ...........:"space(sqlerrp.i) say "SQLERRM ...........:"space(sqlerrm.i) end last_qual = apply_qual.i last_set = set_name.i end end say space(j)" Apply Log entries reported." return /********************************************************************/ /* MAINT_TRAIL: Delete DPropR Apply log entries */ /********************************************************************/ MAINT_TRAIL: say " " say "DELETION OF OBSOLETE APPLY LOG AND EVENT ENTRIES:" say "=================================================" say "Apply Qualifier .................: "asnqual say "Keep DProp data for period of ...: "mtime say " " say "* Deletes log entries vom APPLYTRAIL table, which do not refer" say " to the latest subscription execution." say "* Deletes obsolete event entries from SUBS_EVENT." say " " /*****************************************************************/ /* Delete every unreferenced data or keep data for specif. period*/ /*****************************************************************/ if mtime = "" then sqlstmt = "DELETE FROM ASN.IBMSNAP_APPLYTRAIL A", "WHERE "pred_qual, "AND NOT EXISTS (SELECT 1 FROM ASN.IBMSNAP_SUBS_SET", " WHERE A.APPLY_QUAL = APPLY_QUAL", " AND A.SET_NAME = SET_NAME", " AND A.LASTRUN = LASTRUN ) "; else sqlstmt = "DELETE FROM ASN.IBMSNAP_APPLYTRAIL A", "WHERE "pred_qual, "AND NOT EXISTS (SELECT 1 FROM ASN.IBMSNAP_SUBS_SET", " WHERE A.APPLY_QUAL = APPLY_QUAL", " AND A.SET_NAME = SET_NAME", " AND A.LASTRUN = LASTRUN )", "AND (CURRENT TIMESTAMP - "mtime") > A.LASTRUN"; cc = DOSQL(sqlstmt) if cc = 0 then say space(rxsql_sqlerrd.3)" rows deleted from APPLYTRAIL table." else say "Nothing to maintain, 0 rows deleted from APPLYTRAIL table." say " " /*****************************************************************/ /* Delete every unreferenced data or keep data for specif. period*/ /*****************************************************************/ if mtime = "" then sqlstmt = "DELETE FROM ASN.IBMSNAP_SUBS_EVENT A", "WHERE EXISTS (SELECT 1 FROM ASN.IBMSNAP_SUBS_SET", " WHERE "pred_qual, " AND EVENT_NAME = A.EVENT_NAME", " AND A.EVENT_TIME < LASTSUCCESS ) "; else sqlstmt = "DELETE FROM ASN.IBMSNAP_SUBS_EVENT A", "WHERE EXISTS (SELECT 1 FROM ASN.IBMSNAP_SUBS_SET", " WHERE "pred_qual, " AND EVENT_NAME = A.EVENT_NAME", " AND A.EVENT_TIME < LASTSUCCESS )", "AND CURRENT TIMESTAMP - "mtime" > A.EVENT_TIME"; cc = DOSQL(sqlstmt) if cc = 0 then say space(rxsql_sqlerrd.3)" rows deleted from EVENT table." else say "Nothing to maintain, 0 rows deleted from EVENT table." return /********************************************************************/ /* MODIFY_SUBS: Activate or deactivate subscription sets */ /********************************************************************/ MODIFY_SUBS: arg mode say " " say "DE-/ACTIVATION OF SUBSCRIPTION SETS:" say "====================================" say "Apply Qualifier ...................: "asnqual say "Type of operation (act/deact) .....: "mode if mode = "ACT" then modeconv = 1 if mode = "DEACT" then modeconv = 0 stmt = "UPDATE ASN.IBMSNAP_SUBS_SET", "SET ACTIVATE = "modeconv, "WHERE "pred_qual cc = DOSQL(stmt) if cc = 0 then say space(rxsql_sqlerrd.3)" rows modified on Subscription Set table." else say "Nothing modified, invalid apply qualifier." return /********************************************************************/ /* STOP_TASK: Sends mesage to console to initiate MVS STOP via AOC */ /********************************************************************/ STOP_TASK: Procedure arg message if message = "MESSAGE" ! message = "" then msg = jobname()" SYSLOG MSG TO STOP APPLY VIA AOC." ADDRESS TSO "SEND '"msg"' CN(00)" say "WTO Message issued: "msg" (RC="rc")" return /********************************************************************/ /* ADD_EVENT: Adds an event for specific subscriptions */ /********************************************************************/ ADD_EVENT: say " " say "EVENT GENERATION FOR SUBSCRIPTION SETS : " say "========================================" say "Apply Qualifier .......................: "asnqual say "End-of-Copy-Period passed as parameter : "etime if etime = "" then sqlstmt = "SELECT CURRENT TIMESTAMP,", " CURRENT TIMESTAMP - 1 MINUTE", "FROM SYSIBM.SYSDUMMY1"; else do /*************************************************************/ /* Determine end-of-period timestamp, absolute or RESTART */ /*************************************************************/ if etime = "RESTART" then do /********************************************************/ /* RESTART = max. of all entries for subs set */ /********************************************************/ say "Warning: RESTART specified! Procedure tries to get maximum" say " end-of-period timestamp for specified subscription" say " set or group if sets (if using %_ mask)." sqlstmt = "SELECT CURRENT TIMESTAMP,", " VALUE(MAX(END_OF_PERIOD),", " CURRENT TIMESTAMP - 1 MINUTE)", "FROM ASN.IBMSNAP_SUBS_SET A,", " ASN.IBMSNAP_SUBS_EVENT B ", "WHERE A."pred_qual, "AND A.EVENT_NAME = B.EVENT_NAME", "AND A.ACTIVATE = 1"; end else do /********************************************************/ /* time = specific time (date may be added automatic.) */ /********************************************************/ if length(etime) <= 6 then wetime = date("S")!!left(etime,6,"0") else wetime = left(etime,14,"0") sqlstmt = "SELECT CURRENT TIMESTAMP,", " TIMESTAMP('"wetime"')", "FROM SYSIBM.SYSDUMMY1"; end end cc = DOSQL(sqlstmt) etim = temp.1.1 utim = temp.2.1 say "Event Timestamp set ...................: "etim say "End-of-Copy-Period Timestamp set ......: "utim drop temp.1.1 temp.2.1 say "Apply Qualifier ! Event Name ! Timestamp set ("rxsql_0" list entries)" say "-------------------+--------------------+--------------" sqlstmt = "SELECT DISTINCT EVENT_NAME, APPLY_QUAL", "FROM ASN.IBMSNAP_SUBS_SET", "WHERE "pred_qual, "AND ACTIVATE = 1"; cc = DOSQL(sqlstmt) events = "" do i=1 to rxsql_0 sqlstmt = "INSERT INTO ASN.IBMSNAP_SUBS_EVENT", "VALUES('"event_name.i"','"etim"','"utim"')"; cc = DOSQL(sqlstmt) if cc = 0 then say left(apply_qual.1,18)" ! "left(event_name.i,18)" ! done" else say left(apply_qual.1,18)" ! "left(event_name.i,18)" ! insert failed" events = events"'"event_name.i"'," end if events <> "" then do events = substr(events,1,length(events)-1) CALL LIST_EVENT events end return /********************************************************************/ /* DOSQL: Performs a DB2 SQL statement */ /********************************************************************/ DOSQL: arg stmt /*****************************************************************/ /* Perform a SQL Statement using RXSQL */ /*****************************************************************/ rxsql_db2subsys = ssid /* DB2 Subsystem*/ call RXSQL stmt if stmt = "COMMIT", ! stmt = "ROLLBACK" then call RXSQLEND /* Termination */ else cc = SQLMSG() return cc /********************************************************************/ /* SQLMSG: react on SQL warnings and errors */ /********************************************************************/ SQLMSG: /*****************************************************************/ /* Preparations for issueing messages */ /*****************************************************************/ sqlcode = rxsql_sqlcode sqlerrm = rxsql_sqlerrm /*****************************************************************/ /* Unavailable resource */ /*****************************************************************/ if rxsql_sqlcode = -904 then do say "APPLYIS: Unavailable ressource - contact local ", "DB2/MVS database administrator." say " SQLSTMT="sqlstmt say " SQLCODE="sqlcode say " SQLERRM="sqlerrm call RXSQL "ROLLBACK" call RXSQLEND signal error end /*****************************************************************/ /* Data failure (quote used) */ /*****************************************************************/ if rxsql_sqlcode = -104 ! rxsql_sqlcode = -10 ! rxsql_sqlcode = -180 then do say "APPLYIS: Input data failure - missing quotation mark or formal error" say " SQLSTMT="sqlstmt say " SQLCODE="sqlcode say " SQLERRM="sqlerrm call RXSQL "ROLLBACK" call RXSQLEND signal error end /*****************************************************************/ /* Duplicate value */ /*****************************************************************/ if rxsql_sqlcode = -803 then do say "APPLYIS: An inserted or updated value is duplicate!" say " SQLSTMT="sqlstmt say " SQLCODE="sqlcode say " SQLERRM="sqlerrm call RXSQL "ROLLBACK" call RXSQLEND signal error end /*****************************************************************/ /* Record(s) found or nothing found */ /*****************************************************************/ if rxsql_sqlcode = 100 & rxsql_0 = 0 then return 100 if rxsql_sqlcode = 100 & rxsql_0 > 0 then return 0 /*****************************************************************/ /* Row locked, try again */ /*****************************************************************/ if Rxsql_sqlcode = -911 ! rxsql_sqlcode = -913 then do say "APPLYIS: Deadlock detection" say " SQLSTMT="sqlstmt say " SQLCODE="sqlcode say " SQLERRM="sqlerrm call RXSQL "ROLLBACK" call RXSQLEND signal error end /*****************************************************************/ /* Row limit reached (SELECT) or OK (immediate class) */ /*****************************************************************/ if rxsql_sqlcode = 0, & word(stmt,1) ^= "SELECT" then return 0 else nop /* produces the following message*/ /*****************************************************************/ /* Any other unexpected SQL return code */ /*****************************************************************/ say "APPLYIS: Unexpected SQL error" say " SQLSTMT="stmt say " SQLCODE="sqlcode say " SQLERRM="sqlerrm call RXSQL "ROLLBACK" call RXSQLEND signal error return sqlcode /* ^RXSQLCODE */ /********************************************************************/ /* JOBNAME: Get Jobname stored in MVS internal area */ /********************************************************************/ JOBNAME: Procedure /* ALLE FELDER SIND BESTANDTEIL DES GENERAL USE PRG'ING INTERFACE */ PSATOLD = '21C'X TCB = C2D(STORAGE(C2X(PSATOLD),4)) TIOT = C2D(STORAGE(D2X(TCB+12),4)) TIOCNJOB = STRIP(STORAGE(D2X(TIOT),8)) TIOCSTEP = STRIP(STORAGE(D2X(TIOT+8),8)) Return TIOCNJOB /********************************************************************/ /* Handle problems with syntax or handle error situations */ /********************************************************************/ Syntax: say "APPLYIS Syntax Error." say "APPLYIS ssid,qualifier,option" say " where ssid - DB2 subsystem id" say " qualifier - DPropR Apply Qualifier (SQL-like mask)" say " opt.: qualifier.setname) " say " option - options, as ..." say " SUBS - list subscriptions (dflt)" say " TRAIL - list log (APPLYTRAIL)" say " CHECK - check sub's success" say " WATCH m t - watch execution for specified minutes (m)," say " abend if elapsed or unsuccessful Apply sub's." say " List un/successful Apply subscriptions." say " Allow tolerance (t), e.g. 2 HOURS, 1 DAY etc." say " MAINT [p] - delete from APPLYTRAIL and SUBSEVENT," say " keep info for a specified time period (e.g. 1 WEEK)" say " dflt.: every unreferenced entry will be deleted" say " ACT/DEACT - activate/deactivate subscription" say " SYNCH - synchronize source register -> target subs-sets" say " EVENT [t| - add event timestamp (event and end-of-period time)," say " RESTART] - add new event but use previous end-of-period time," say " dflt.: current timestamp and curr. tstmp - 1 minute," say " opt.: t=end-of-copy-period [yyyymmdd]hhmmss" say " RESTART=use previous end-of-copy period" say " STOP [msg]- send AOC STOP APPLY message to MVS SYSLOG" ERROR: say "" if sysvar(SYSISPF) = "NOT ACTIVE" then do say "Rexx Procedure APPLYIS abends with U0001." address ATTACH "D2PABND" exit 0 end say "Rexx Procedure APPLYIS abends with RC=20." exit 20
Comments
Comments are closed.