Dienstprogramme sortieren - AWS Mainframe-Modernisierung

AWS Der Mainframe Modernization Service (Managed Runtime Environment Experience) steht Neukunden nicht mehr zur Verfügung. Funktionen, die dem AWS Mainframe Modernization Service (Managed Runtime Environment-Erfahrung) ähneln, finden Sie unter AWS Mainframe Modernization Service (Self-Managed Experience). Bestandskunden können den Service weiterhin wie gewohnt nutzen. Weitere Informationen finden Sie unter Änderung der Verfügbarkeit von AWS Mainframe Modernization.

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Dienstprogramme sortieren

Die Sortierprogramme basieren auf Datensätzen, deren Referenz für das Hilfsprogramm eine besondere Bedeutung hat. Daher haben alle Sortierprogramme auf der modernisierten Seite dasselbe Aufrufmuster in Groovy-Skripten:

mpr.withFileConfigurations(<FILE CONFIGURATIONS DETAILS>...) .withParameters(params) .runProgram("<SORT UTILITY ALIAS>")

wo mpr ist eine MainProgramRunner Instanz (siehe den Abschnitt Skripte, die Programme aufrufen auf dieser Seite). Die Aliase für die Sortierprogramme sind in den folgenden Abschnitten angegeben.

Die Einträge DD (Datensatzdefinitionen) aus dem JCL-Skript wurden als Einträge in den Details der Dateikonfiguration modernisiert, die als Argument für die Methode dienen. mpr.withFileConfigurations() In den folgenden Beispielen finden Sie Veranschaulichungen dieses Konzepts.

SORT/SYNCSORT/ICEMAN

Zweck

Dieses Programm emuliert verschiedene Mainframe-SORT-Dienstprogramme, die auf Grundlage der angegebenen Kriterien sort/merge/copy Daten aus Datensätzen verarbeiten. Die folgenden Programmaliase können verwendet werden (und entsprechen dem Namen des entsprechenden Legacy-Sortierprogramms):

  • SORT

  • SYNCSORT

  • ICEMAN

Die Details zu den SORT/MERGE Direktiven auf den Kontrollkarten und zu den Funktionen der alten Sortierprogramme werden hier nicht aufgeführt, sollten aber aus den vorhandenen Dokumentationen zu den entsprechenden älteren Plattformen abgerufen werden.

Signatur

Das Programm verwendet keine Argumente, sondern stützt sich stattdessen auf spezifische Datensatzreferenzen:

  • Der SYSIN Datensatz (auch bekannt als die „Kontrollkarte“) enthält die Steueranweisungen sort/merge

  • Der optionale SYMNAMES Datensatz enthält Anweisungen zur Variablenersetzung im SYSIN-Inhalt

  • Der optionale SORTXSUM Datensatz SORTXDUP or kann verwendet werden, um doppelte Datensätze zu speichern

  • Die Datensätze, denen zu verarbeitende Datensätze vorangestellt sind, SORTIN oder die Datensätze SORTDBIN enthalten, die verarbeitet werden sollen (Eingaben)

  • Der SORTOUT Datensatz enthält die Ergebnisse des Programms (Ausgabe)

  • Die SORTWK Definitionen für SORT WORK-Datensätze, die in einigen älteren Job-Skripten zu finden sind, werden ignoriert (und im modernisierten Aufruf nicht berücksichtigt). Sortierarbeitsdatensätze werden in der modernen Umgebung immer dynamisch zugewiesen

  • Die beiden Datensätze, deren DD mit SORTJN (Präfix) beginnt, enthalten Datensätze, die von Join-Key-Direktiven betroffen sein werden (die verwendet werden, um Datensätze während des Sortiervorgangs zu verbinden)

Betrachten wir zum Beispiel die folgenden Join-Key-Direktiven:

JOINKEYS FILE=F1,FIELDS=(13,5,A) JOINKEYS FILE=F2,FIELDS=(24,5,A)

Hier hat der Join-Key die Länge 5 und beginnt bei:

  • Position 13 für Datensätze im Datensatz SORTJNF1 (Verkettung von SORTJN Präfix und Datei) F1

  • Position 24 für Datensätze im Datensatz SORTJNF2 (Verkettung von Präfix und Datei) SORTJN F2

Prüfungen/Behandlung von Fehlern

  • Falls die Eingabedatei (SORTIN) eine SHR Disposition hat, aber nicht gefunden werden kann, wird eine Fehlermeldung protokolliert, der Programmrückgabecode wird auf 1 gesetzt und der Programmlauf wird angehalten (es erfolgt keine Sortierung, es wird keine Ausgabe erzeugt)

In den folgenden Fällen wird eine RuntimeException Meldung ausgegeben, in der eine spezielle Nachricht gespeichert ist:

  • Wenn der Programmaufruf eine Verbindung zu einer Datenbank erfordert (wenn ein SORTDBIN Datensatz verwendet wird, nichtSORTIN), aber keine gültige Datenquelle gefunden werden kann

  • Wenn die Ausgabedatei (SORTOUT) nicht richtig definiert ist

  • Wenn ein auf der Steuerkarte gefundener Befehl nicht verstanden werden kann oder nicht unterstützt wird

  • Wenn nicht genau zwei Eingabedateien für einen SORT JOINKEYS Fall bereitgestellt werden

Beispiel für die Verwendung

Beispiel MERGE

Hier ist ein ICEMAN Beispielaufruf aus einem Job-Skript-Snippet:

Die Steuerkarte ist eingebunden und enthält Befehle zum Zusammenführen von Feldern aus den Eingabedateien (siehe den Eintrag) SYSIN

//* //PASOSO03 EXEC PGM=ICEMAN,REGION=0M //SORTIN01 DD DSN=input(input809a.data),DISP=SHR,LRECL=10 //SORTIN02 DD DSN=input(input809b.data),DISP=SHR,LRECL=10 //SORTOUT DD DSN=output(out809.txt),DISP=(,PASS),LRECL=10 //SORTWK01 DD SPACE=(281,(156300,156300),RLSE),AVGREC=U //SORTWK02 DD SPACE=(281,(156300,156300),RLSE),AVGREC=U //SYSIN DD * MERGE FIELDS=(1,6,PD,A,7,2,CH,A) END /*

Und das passende modernisierte Groovy-Snippet — bitte beachten Sie, dass, wie bereits erwähnt, die SORTWK Eingaben während des Modernisierungsprozesses nicht berücksichtigt werden und dass die integrierte Kontrollkarte genau dem Inhalt der alten Kontrollkarte entspricht.

// STEP PASOSO03 - PGM - ICEMAN*************************************************** def stepPASOSO03(Object shell, Map params, Map programResults){ shell.with { if (checkValidProgramResults(programResults)) { return execStep("PASOSO03", "ICEMAN", programResults, { mpr .withFileConfigurations(new FileConfigurationUtils() .withJobContext(jobContext) .fileSystem("SORTIN01") .path("input(input809a.data)").recordSize(10) .disposition("SHR") .build() .fileSystem("SORTIN02") .path("input(input809b.data)").recordSize(10) .disposition("SHR") .build() .fileSystem("SORTOUT") .path("output(out809.txt)").recordSize(10) .normalTermination("PASS") .build() .fileSystem("SYSIN") .stream( """ MERGE FIELDS=(1,6,PD,A,7,2,CH,A) END """, getEncoding()) .build() .getFileConfigurations()) .withParameters(params) .runProgram("ICEMAN") }) } } }

Einfaches SORT-Beispiel

Ein einfacher älterer SORT-Schritt (Job-Skript-Snippet) mit integrierter Steuerkarte, übernommen aus der CardDemo-Beispielanwendung:

//********************************************************************* //* CREATE COPY OF TRANSACT FILE WITH CARD NUMBER AND TRAN ID AS KEY //********************************************************************* //STEP010 EXEC PGM=SORT //SORTIN DD DISP=SHR,DSN=AWS.M2.CARDDEMO.TRANSACT.VSAM.KSDS //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SORTOUT DD DSN=AWS.M2.CARDDEMO.TRXFL.SEQ, // DISP=(NEW,CATLG,DELETE),UNIT=SYSDA, // DCB=(LRECL=350,BLKSIZE=3500,RECFM=FB), // SPACE=(CYL,(1,1),RLSE) //SYSIN DD * SORT FIELDS=(263,16,CH,A,1,16,CH,A) OUTREC FIELDS=(1:263,16,17:1,262,279:279,50) /*

und das passende modernisierte Groovy-Skript-Snippet:

// STEP STEP010 - PGM - SORT****************************************************** def stepSTEP010(Object shell, Map params, Map programResults){ shell.with { if (checkValidProgramResults(programResults)) { return execStep("STEP010", "SORT", programResults, { mpr .withFileConfigurations(new FileConfigurationUtils() .withJobContext(jobContext) .bluesam("SORTIN") .dataset("AWS.M2.CARDDEMO.TRANSACT.VSAM.KSDS") .disposition("SHR") .build() .systemOut("SYSPRINT") .output("*") .build() .systemOut("SYSOUT") .output("*") .build() .fileSystem("SORTOUT") .path("AWS.M2.CARDDEMO.TRXFL.SEQ").recordSize(350) .disposition("NEW") .normalTermination("CATLG") .abnormalTermination("DELETE") .build() .fileSystem("SYSIN") .stream( """ SORT FIELDS=(263,16,CH,A,1,16,CH,A) OUTREC FIELDS=(1:263,16,17:1,262,279:279,50)""", getEncoding()) .build() .getFileConfigurations()) .withParameters(params) .runProgram("SORT") }) } } }

Bitte beachten Sie, dass die integrierte Kontrollkarte unverändert verwendet wird, ohne dass der Inhalt der alten Kontrollkarte geändert wird.

EISWERKZEUG

Zweck

Das ICETOOL-Hilfsprogramm wird verwendet, um mehrere Operationen an Datensätzen in einem einzigen Arbeitsschritt durchzuführen (Datenmanipulation, Sortierung und Analyse).

Die folgenden Kernoperatoren werden unterstützt:

  • COPY- Kopiert Daten von Eingabe- in Ausgabedateien

  • SORT- Sortiert Daten anhand der angegebenen Sortierkarten/Kriterien

  • SELECT- Filtert und wählt bestimmte Datensätze auf der Grundlage von Bedingungen aus

  • SPLICE- Merges/joins Daten aus mehreren Quellen

  • COUNT- Zählt Datensätze, die bestimmte Kriterien erfüllen

  • OCCUR- Analysiert Vorkommensmuster in Daten

Für den SPLICE-Operator verwendet das Hilfsprogramm einen Multithread-Ansatz, der auf Strategien zur Datenaufteilung basiert, um eine optimierte Leistung zu gewährleisten.

Einzelheiten zu den Operatoren sollten der entsprechenden Dokumentation der älteren Plattform entnommen werden.

Signatur

Das ICETOOL Hilfsprogramm verwendet keine Parameter, sondern stützt sich auf bestimmte Datensätze:

  • TOOLINDer Datensatz enthält die Steueranweisungen, die vom Hilfsprogramm verarbeitet werden sollen

  • TOOLMSGund DFSMSG Datensätze werden vom modernisierten ICETOOL Hilfsprogramm derzeit nicht verwendet (ignoriert)

  • INist das Präfix für Eingabedatensätze (zu verarbeitende Datensätze)

  • OUTist das Präfix für Ausgabedatensätze (Datensätze, die aus der Verarbeitung resultieren)

  • andere Datensätze könnten durch Steueranweisungen auf der Steuerkarte referenziert werden

Prüfungen/Behandlung von Fehlern

In den folgenden Fällen RuntimeException wird a mit einer entsprechenden Meldung ausgelöst:

  • Wenn der in einer der Steueranweisungen verwendete Operator nicht unterstützt wird

  • Für jeden Operator, wenn eine nicht unterstützte Direktive bereitgestellt wird

Anwendungsbeispiel

ICETOOL SORT-Beispiel

Hier ist ein Legacy-JCL-Beispiel, das ICETOOL für Sortierzwecke verwendet:

  • Jede Steueranweisung des SORT-Operators verwendet eine spezielle Steuerkarte, deren Referenz durch das USING-Schlüsselwort angegeben wird

  • alle Kontrollkarten werden nach der TOOLIN Definition definiert und sind eingebunden (siehe SEL1CNTL und die folgenden *CNTL Einträge)

//SAMPLO52 EXEC PGM=ICETOOL,REGION=1024K //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //IN1 DD DSN=input(input846a.data),DISP=SHR // DCB=(RECFM=F,LRECL=8) //IN2 DD DSN=input(input846b.data),DISP=SHR // DCB=(RECFM=F,LRECL=8) //OUT1 DD DSN=output(out846a.txt),DISP=(,CATLG) // DCB=(RECFM=F,LRECL=8) //OUT2 DD DSN=output(out846b.txt),DISP=(,CATLG) // DCB=(RECFM=V) //OUT3 DD DSN=output(out846c.txt),DISP=(,CATLG) // DCB=(RECFM=V) //TOOLIN DD * SORT FROM(IN1) TO(OUT1) USING(SEL1) SORT FROM(IN2) TO(OUT1) USING(SEL2) SORT FROM(IN1) TO(OUT2) USING(SEL3) SORT FROM(IN2) TO(OUT2) USING(SEL4) SORT FROM(IN1) TO(OUT3) USING(SEL5) SORT FROM(IN2) TO(OUT3) USING(SEL6) /* //SEL1CNTL DD * OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')) //* //SEL2CNTL DD * OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')) //* //SEL3CNTL DD * OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' ' //* //SEL4CNTL DD * OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' ' //* //SEL5CNTL DD * OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' ' //* //SEL6CNTL DD * OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,7,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' ' //*

Nach der Modernisierung sieht der passende groovige Skriptausschnitt wie folgt aus:

// STEP SAMPLO52 - PGM - ICETOOL************************************************** def stepSAMPLO52(Object shell, Map params, Map programResults){ shell.with { if (checkValidProgramResults(programResults)) { return execStep("SAMPLO52", "ICETOOL", programResults, { mpr .withFileConfigurations(new FileConfigurationUtils() .withJobContext(jobContext) .systemOut("TOOLMSG") .output("*") .build() .systemOut("DFSMSG") .output("*") .build() .fileSystem("IN1") .path("input(input846a.data)").recordSize(8) .disposition("SHR") .build() .fileSystem("IN2") .path("input(input846b.data)").recordSize(8) .disposition("SHR") .build() .fileSystem("OUT1") .path("output(out846a.txt)").recordSize(8) .normalTermination("CATLG") .build() .fileSystem("OUT2") .path("output(out846b.txt)").rdw(true) .normalTermination("CATLG") .build() .fileSystem("OUT3") .path("output(out846c.txt)").rdw(true) .normalTermination("CATLG") .build() .fileSystem("TOOLIN") .stream( """ SORT FROM(IN1) TO(OUT1) USING(SEL1) SORT FROM(IN2) TO(OUT1) USING(SEL2) SORT FROM(IN1) TO(OUT2) USING(SEL3) SORT FROM(IN2) TO(OUT2) USING(SEL4) SORT FROM(IN1) TO(OUT3) USING(SEL5) SORT FROM(IN2) TO(OUT3) USING(SEL6) """, getEncoding()) .build() .fileSystem("SEL1CNTL") .stream( """ OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')) """, getEncoding()) .build() .fileSystem("SEL2CNTL") .stream( """ OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*'))""", getEncoding()) .build() .fileSystem("SEL3CNTL") .stream( """ OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' '""", getEncoding()) .build() .fileSystem("SEL4CNTL") .stream( """ OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' '""", getEncoding()) .build() .fileSystem("SEL5CNTL") .stream( """ OPTION COPY OUTFIL BUILD=(1,8,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' '""", getEncoding()) .build() .fileSystem("SEL6CNTL") .stream( """ OPTION COPY,SKIPREC=1 OUTFIL BUILD=(1,7,JFY=(SHIFT=LEFT,TRAIL=C'*')), FTOV,VLTRIM=C' '""", getEncoding()) .build() .getFileConfigurations()) .withParameters(params) .runProgram("ICETOOL") }) } } }

Hinweise:

  • Die integrierten Kontrollkarten werden „so wie sie sind“ verwendet. Es wurde keinerlei Veränderung gegenüber den alten Kontrollkarten vorgenommen

  • TOOLMSGund DFSMSG sind in der modernisierten Version definiert, werden aber zur Laufzeit ignoriert

  • Sowohl in älteren als auch in modernisierten Versionen sind die Kontrollkarten mit dem CNTL Suffix definiert, in den Direktiven aus dem Datensatz wird jedoch ohne das Suffix referenziert: z. B. InSORT FROM(IN1) TO(OUT1) USING(SEL1), der USING(SEL1) bezieht sich auf die TOOLIN Datensatzdefinition SEL1CNTL

ICETOOL COPY-BEISPIEL

Hier ist ein weiteres ICETOOL-Beispiel, das den COPY-Operator verwendet. Das TOOLIN ist im JCL-Skriptausschnitt enthalten:

//SAMPLO51 EXEC PGM=ICETOOL,REGION=1024K //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //IN1 DD DSN=input(input831.data),DISP=SHR // DCB=(RECFM=F,LRECL=12) //OUT1 DD DSN=output(out831a.txt),DISP=OLD // DCB=(RECFM=F,LRECL=12) //OUT2 DD DSN=output(out831b.txt),DISP=OLD // DCB=(RECFM=F,LRECL=12) //TOOLIN DD * COPY FROM(IN1) TO(OUT1,OUT2) USING(SEL1) /* //SEL1CNTL DD * OPTION COPY OUTFIL INCLUDE=(7,2,CH,EQ,C'10') //*

Und hier ist der passende modernisierte Groovy-Skriptausschnitt:

// STEP SAMPLO51 - PGM - ICETOOL************************************************** def stepSAMPLO51(Object shell, Map params, Map programResults){ shell.with { if (checkValidProgramResults(programResults)) { return execStep("SAMPLO51", "ICETOOL", programResults, { mpr .withFileConfigurations(new FileConfigurationUtils() .withJobContext(jobContext) .systemOut("TOOLMSG") .output("*") .build() .systemOut("DFSMSG") .output("*") .build() .fileSystem("IN1") .path("input(input831.data)").recordSize(12) .disposition("SHR") .build() .fileSystem("OUT1") .path("output(out831a.txt)").recordSize(12) .disposition("OLD") .build() .fileSystem("OUT2") .path("output(out831b.txt)").recordSize(12) .disposition("OLD") .build() .fileSystem("TOOLIN") .stream( """ COPY FROM(IN1) TO(OUT1,OUT2) USING(SEL1) COPY FROM(IN1) TO(OUT3,OUT4) COPY FROM(IN1) TO(OUT4) COPY FROM(IN1) TO(OUT5,OUT6) """, getEncoding()) .build() .fileSystem("SEL1CNTL") .stream( """ OPTION COPY OUTFIL INCLUDE=(7,2,CH,EQ,C'10')""", getEncoding()) .build() .getFileConfigurations()) .withParameters(params) .runProgram("ICETOOL") }) } } }

MFSORT

Zweck

Dieses Hilfsprogramm soll das Verhalten des Sortierprogramms MFSORT nachahmen, das in Micro Focus-Umgebungen zu finden ist (es wird normalerweise über die Befehlszeile oder in Skripten in älteren Umgebungen aufgerufen).

Intern delegiert das Programm die eigentlichen Sortiervorgänge an das Hilfsprogramm. SORT/SYNCSORT/ICEMAN

Signatur

Nur die folgende Legacy-Syntax wird unterstützt: mfsort take <control card>

Der direkte Befehl call as mfsort <instructions> wird NICHT unterstützt.

Sie benötigt kein Argument; die Take-Direktive wird mithilfe eines Datensatzes emuliertTAKE, auf den als verwiesen wird und der die Befehle für die Ausführung von MFSORT enthält.

Prüfungen//Behandlung von Fehlern

  • Wenn der TAKE Datensatz fehlt oder ungültig ist, RuntimeException wird ein ausgelöst

  • Angesichts der Delegation von MFSORT zu SORT Prüfungen/Behandlung von Fehlern gelten sie auch hier

Anwendungsbeispiel

Der folgende Befehlsaufruf zeigt ein Beispiel für die Verwendung von MFSORT:

mfsort take TESTSRT1.CTL

Hier ist der passende modernisierte, angepasste Groovy-Skriptausschnitt:

mpr.withFileConfigurations(new FileConfigurationUtils() .fileSystem("TAKE") .path("input(TESTSRT1.CTL)") .build() .getFileConfigurations()) .withArguments("input") // relative path for use and give files .runProgram("MFSORT");