Also, die "einfachste" Variante für ILE-Cobol, ist, die OPM-Programme einfach nur auf ILECBL umzustellen und zu wandeln. Beim Erstellen gib einfach eine ACTGRP mit Namen und nicht mit *CALLER an.
Beende die Programme grundsätzlich mit EXIT PROGRAM. Ich habe früher immer EXIT PROGRAMM und GOBACK direkt hintereinander verwendet, so dass das PGM sowohl als Upro als auch als Hauptprog verwendet werden konnte.
Beachte allerdings bei wiederholten Aufrufen den Status geöffneter Dateien.

RUN UNIT ist das alte COBOL-Problem (was RPG'ler nicht kennen), dass STOP RUN alle Programme der RUN UNIT beendet (PGMA->PGMB->PGMC->... STOP RUN: bis einschließlich PGMA beendet). Mit ACTGRP's gibt es eben eine RUN UNIT pro ACTGRP.

Service-PGM'e sind im ersten Schritt nicht erforderlich. Dies sind Programme, die häufig benötigte Routinen enthalten sollen. Alle SQLxxx-Funktionen liegen z.B. in Service-PGM'en.

Wenn man mit CALL PROCEDURE arbeitet, sind das sog. STATIC-Calls, da der Name nicht in einer Variablen stehen kann und bereits zum Aufrufzeitpunkt (Service-PGM'e) bzw. zur Compile-Zeit die Adresse zum Modul / zur Routine ermittelt wird.

Mit CALL aufgerufene PGM'e sind dynamisch, da erst zur Laufzeit das externe Programm über die Libliste ermittelt wird. Dabei ist es unerheblich, ob ein OPM- oder ILE-Programm aufgerufen wird.

Nun zu deinem Test:

Dieses Vorgehen (ich bitte um Entschuldigung) war ja sowas von unsinnig !!!
Mit 19 Millisekunden pro Satz bist du doch noch relativ fix gewesen, wenn man sich mal vorstellt, was da alles ablaufen musste.

Beim Erstellen der DTAQ ist zu beachten, ob jeder QSNDDTAQ unbedingt auf die Platte geschrieben werden muss. Dies sollte man abschalten, da es nach diesem Verfahren keinen Sinn macht, DTAQ-Inhalte über IPL hinweg aufzuheben.

Und was sollte diese Funktion bringen ?

Wenn nur Daten gelesen werden sollen, ist keine SQL-Prozedur erforderlich, da ein direkter Select/Fetch BEDEUTEND schneller abgewickelt wird !!!
Das gleiche gilt auch für INSERT/UPDATE/DELETE !!!
Insbesonders im Multiuser-Betrieb würde eigentlich jeder User einen solchen Batchjob benötigen, da du sonst Satzsperren nicht unter Kontrolle hast (UPDATE ohne READ).

SQL-Prozeduren sind nur dann sinnvoll, wenn ein komplexer Vorgang KOMPLETT auf den Server verlagert werden kann. Will heißen, dass durch Parameter gezielt bestimmte Funktionen ausgelöst werden (z.B. ein Buchungsvorgang über mehrere Dateien) und nur das Ergebnis (falls überhaupt) wieder benötigt wird.

Es kann auch sinnvoll sein, wenn z.B. eine Subfile (Liste) gefüllt werden muss und die Daten nicht einfach durch einen Select (egal wie komplex) ermittelt werden können.

Untersuche deine Programme doch mal nach folgenden Kriterien:
1. Dialog-Programme
Diese kann man einfach erstmal auf SQL umstellen, wobei ggf. geprüft werden sollte, welche Felder einer Datei überhaupt benötigt werden (Crossref) um die Selects/Updates zu verkürzen.

2. Unterprogramme
Dies sind typischerweise Programme, die als SQL-Prozeduren in Frage kommen, da sie keine Benutzeraktion benötigen und die Paramter (Ein-/Ausgabe) per Linkage-Section ja vorgegeben sind.
Dies können natürlich auch CLP's sein, die z.B. einen SBMJOB für Batch auslösen.

Teste doch mal deinen START / READ NEXT / READ INVALID direkt als SQL-Programm in 2 Varianten:
1. mit komplettem Satz
2. nur mit relevanten Feldern (max. 10)

Für START/READ NEXT benötigst du einen Cursor (OPEN/FETCH into, hier ist auch Blocken möglich).
Für READ INVALID benötigts du keinen Cursor, da ein direktes SELECT INTO möglich ist.