Anfrage von einem Kunden: Im Tagesabschluss wird ein Subsystem beendet und dann wieder gestartet. Manchmal passiert es, dass das Subsystem noch nicht beendet ist. Bei dem Versuch, das Subsystem zu starten bricht der Job ab. Welche Möglichkeiten gibt es, um das zu verhindern?
Was ist für die Prüfung zu beachten?
Um zu ermitteln ob ein Subsystem noch aktiv ist, bevor es wieder gestartet wird, gibt es mehrere Möglichkeiten. Der Versuch, ein Subsystem zu starten, das noch nicht beendet ist bzw. das noch aktiv ist, führt zu einem Abbruchfehler, wie die folgenden Abbildungen zeigen.

Und das ist die Abbruchmeldung CPF1010:

Die einfachste Möglichkeit, diesen Fehler abzufangen, ist die Verwendung der CL-Anweisung MONMSG.
In einer weiteren Variante könnte ein Service verwendet werden, den SQL als View zur Verfügung stellt. Mit diesem Service kann der Status des Subsystems ermittelt werden.
Wer das lieber mit einem RPG-Programm lösen möchte, könnte das auch mit Hilfe von C-Prozeduren tun, die als Prototype im Programm definiert werden müssen.
Die Lösung mit CL und MONMSG
Die einfachste Lösung kann im CL-Programm mit der Verwendung der MONMSG-Anweisung erfolgen.
pgm
/*-----------------------------------*/
/* Subsystem beenden und wieder starten */
/* TB 20.06.2023 */
/*-----------------------------------*/
WRKACTJOB SBS(QWEBQRY21)
ENDSBS SBS(QWEBQRY21) OPTION(*IMMED) DELAY(30) +
ENDSBSOPT(*NOJOBLOG)
MONMSG MSGID(CPF0000)
WRKACTJOB SBS(QWEBQRY21)
m1:
STRSBS SBSD(QWEBQRY/QWEBQRY21)
MONMSG MSGID(CPF1010) EXEC(DO)
SNDUSRMSG MSG('SBS noch aktiv') /* nur zum Testen */
DLYJOB DLY(10)
GOTO CMDLBL(M1)
enddo
endpgm
CL-Quelle SbsStrEnd
Wie bereits oben erwähnt, führt der Versuch, ein Subsystem zu starten, das noch aktiv ist, zu einem Fehler mit der Identität CPF1010. Dieser Fehler kann mit MONMSG abgefangen werden.
Lösung mit CL und SQL-Service
SQL verfügt über einen Service, mit der Zustand eines Subsystems ermittelt werden kann. Der Service QSYS2.SUBSYSTEM_INFO wird als View zur Verfügung gestellt.
Hier sind einige Beispiele für die Verwendung des SQL-Service:
/*-------------------------------------------------------------------------------*/
-- Beispiele für QSYS2.SUBSYSTEM_INFO
-- alle Subsysteme, die AKTIV sind
SELECT *
FROM QSYS2.SUBSYSTEM_INFO
WHERE STATUS = 'ACTIVE';
-- welche Stati von Subsystemen gibt es?
select distinct status from qsys2.subsystem_info; -- ACTIVE u. INACTIVE
-- alle Subsysteme mit Status INACTIVE
SELECT *
FROM QSYS2.SUBSYSTEM_INFO
WHERE STATUS = 'INACTIVE';
-- Status des Subsystems QWEBQRY21 in Bibliothek QWEBQRY
select status, Subsystem_Description_Library from qsys2.subsystem_info
where Subsystem_Description = 'QWEBQRY21' and Subsystem_Description_Library = 'QWEBQRY';
-- Rückgabe von Wert '1', falls Subsystem AKTIV
select '1' from qsys2.subsystem_info
where Subsystem_Description = 'QWEBQRY21' and Subsystem_Description_Library = 'QWEBQRY' and status = 'ACTIVE';
STOP;
/*-------------------------------------------------------------------------------*/
SQL-Script 01: Beispiele für die Verwendung von QSYS2.SUBSYSTEM_INFO
In den folgenden Beispielen wird jeweils ein SQL Compound Statement gezeigt, in welchem der Status eines Subsystems abgefragt wird. Die Abfrage erfolgt innerhalb einer Schleife, die solange ausgeführt wird, bis das Subsystem beendet wird.
Zusätzlich wird der jeweilige Status des Subsystems in das Joblog geschrieben. Dazu wird folgende SQL-Prozedur verwendet:
SYSTOOLS.LPRINTF
Beispiel für die Verwendung der Prozedur:
SYSTOOLS.LPRINTF(‘Dieser Text wird ins Joblog geschrieben.‘;
/*-------------------------------------------------------*/
-- Compound Statement
-- wird so lange ausgeführt bis Subsystem nicht mehr aktiv
-- als Skript ablegen und in CL-Programm mit RUNSQLSTM ausführen
/*---------------*/
/* mit GOTO */
/*---------------*/
Begin
declare status int;
declare v_Nachricht varchar(100);
declare zaehler decimal (6,0);
SET status = 1;
M1:
Set status = (select 1 from qsys2.subsystem_info
where Subsystem_Description = 'QWEBQRY21' and Subsystem_Description_Library = 'QWEBQRY' and status = 'ACTIVE');
-- status = 1 -- Status = 'AKTIV'
if status = 1
THEN
call qsys2.qcmdexc('SNDBRKMSG MSG(AKTIV) TOMSGQ(E550AB)'); -- nur zum Testen
Set v_Nachricht = '***Subsystem ist noch aktiv *** Status = ' || Status || ' Zähler = ' || zaehler;
call qsys2.qcmdexc('DLYJOB DLY(20)');
set zaehler = zaehler + 1;
call systools.lprintf('Subsystem ist noch aktiv');
goto M1;
else
call qsys2.qcmdexc('SNDBRKMSG MSG(NICHT_AKTIV) TOMSGQ(E550AB)'); -- nur zum Testen
Set v_Nachricht = '***Subsystem ist nicht mehr aktiv *** Status = ' || Status;
call systools.lprintf('***Subsystem ist nicht mehr aktiv*** '); -- geht
end if;
end;
SQL-Script 02: Compound Statement mit GOTO
/*-------------------------------------------------------------------*/
/* Mit WHILE-Schleife */
/*--------------------------*/
BEGIN
Declare Status_Sbs Varchar(10);
Set Status_Sbs = (
Select Status
From Qsys2.Subsystem_Info
Where Subsystem_Description = 'QWEBQRY21' And Subsystem_Description_Library =
'QWEBQRY');
call systools.lprintf('Status Subsystem:' concat Status_Sbs); -- funktioniert
WHILE (Status_Sbs <> 'INACTIVE') Do
Call Qsys2.Qcmdexc('SNDBRKMSG MSG(''Subsystem QWEBQRY21 ist noch AKTIV'') TOMSGQ(E550AB)'); -- nur zum Testen
Call Qsys2.Qcmdexc('DLYJOB DLY(20)');
Set Status_Sbs = (
Select Status
From Qsys2.Subsystem_Info
Where Subsystem_Description = 'QWEBQRY21' And Subsystem_Description_Library
= 'QWEBQRY');
call systools.lprintf('Status Subsystem:' concat Status_Sbs); -- funktioniert
END WHILE;
END;
STOP;
/*------------------------------------------------------------------------------------*/
SQL-Script 03: Compound Statement mit WHILE-Schleife
Die Verwendung eines Compound Statements kann nun mit Hilfe der CL-Anweisung RUNSQLSTMT erfolgen. Dazu wird das Statement in einer Teildatei einer physischen Quellendatei abgespeichert und dann vor dem Starten des Subsystems mit RUNSQLSTM ausgeführt.
Lösung mit RPG und zwei C-Prozeduren
Falls Sie lieber eine Lösung mit RPG favorisieren, empfehle ich Ihnen die folgenden Beispiele:
Verwendete Features
In diesem Artikel wurden die folgenden Features verwendet:
- MONMSG – CL-Anweisung
- DLYJOB – CL-Anweisung
- SQL Compound Statement – SQL Konstrukt
- QSYS2.SUBSYSTEM_INFO – SQL Service
- QSYS2.QCMDEXC – SQL-Prozedur
- SYSTOOLS.LPRINTF – SQL-Prozedur
Vorschau:
Sobald es wieder Neuerungen in ACS gibt, melde ich mich wieder.
Bis dahin wünsche ich Ihnen weiterhin viel Spaß beim Vermehren Ihrer Fertigkeiten.
Den Autor Theo Bär erreichen Sie unter:
EDV-Beratung Theo Bär
Ringmauerweg 1
69250 Schönau
Tel.: (+49) 6228 912 630
E-Mail: info@edv-baer.com
Für 88 Euro gibt’s hier sechs Monate lang tiefgreifendes IBM i und SQL Wissen. Hier kann man abonnieren.