SQL-Daten
SQL ist eine Sprache, die mit einem Verwaltungssystem für relationale Datenbanken kommuniziert. Dieses System steuert wiederum eine Datenbank, die Geschäftsinformationen in vernetzten Tabellen verwaltet.
- Bei Ausführung allgemeiner und unkomplizierter Tasks können EGL-Anweisungen zur Ausführung sämtlicher E/A-Operationen verwendet werden (siehe Datensätze lesen und schreiben). In diesem Fall erstellt EGL alle tatsächlichen SQL-Anweisungen.
- Mit einer #sql-Direktive können eigene SQL-Anweisungen in den EGL-Code eingefügt werden.
Bei EGL besteht sogar die Möglichkeit, die beiden Verfahren zu kombinieren. Sie können über den EGL-Code auf die von EGL generierten SQL-Anweisungen zugreifen und diese ändern (siehe Implizite SQL-Anweisungen anzeigen).
- Anweisungen zur Verbindung von EGL mit der SQL-Datenbank (siehe SQL-Datenbankverbindung erstellen)
- Direktaufrufe zur Erstellung von SQL-Datensätzen (siehe SQL-Tabellendaten abrufen)
- Direktaufrufe zur Erstellung vollständiger SQL-Anwendungen (siehe Datenzugriffsanwendung erstellen)
EGL-Ansatz
In der folgenden Tabelle wird beschrieben, wie EGL für die Interaktion mit einer relationalen Datenbank verwendet werden kann.
| SQL-Ziel | EGL-Ansatz |
|---|---|
| Einfache SQL-Datenbearbeitung (SELECT, UPDATE, INSERT, DELETE). Primärschlüssel steuert WHERE und ORDER BY. | EGL-Schlüsselwörter (get, replace, add, delete) verwenden und EGL zur Generierung von implizitem SQL veranlassen. |
| Einfache SQL-Datenbearbeitung mit wiederverwendbarer angepasster WHERE-Klausel | Angepasste WHERE-Klausel in die Eigenschaft defaultSelectCondition einfügen. |
| SQL-SELECT-Anweisungen mit angepasster WHERE-Klausel | Explizites SQL über die #sql-Direktive verwenden. |
| SQL-Anweisung JOIN für Tabellen | Die Funktion 'SQL abrufen' in der Workbench verwenden und dann die Tabellen
in Primär- und Fremdschlüsseln mit der Eigenschaft defaultSelectCondition
korrekt verknüpfen:
|
| Abgeleitete Daten in SELECT-Befehl (z. B. MAX() ider AVG()) | Explizites SQL über die #sql-Direktive verwenden und die abgeleiteten Felder in die geschweiften Klammern einfügen. |
| Einen angepassten SQLRecord erstellen, wobei die Eigenschaft column für die einzelnen Felder den abgeleiteten oder berechneten Ausdruck angibt. | |
| Komplexe oder angepasste SQL-Anweisung UPDATE, INSERT oder DELETE | EGL-Anweisung replace, add oder delete mit explizitem SQL verwenden (#sql-Direktive). |
| Explizites SQL über die Anweisung execute #sql verwenden. | |
| Andere SQL-Anweisungen als die für einfache Datenbearbeitung (z. B. CREATE TABLE) | Explizites SQL über die Anweisung execute #sql verwenden. |
| Dynamisches SQL (vorbereitete SQL-Anweisung) | Explizites SQL über die Anweisung execute #sql verwenden. |
| Gespeicherte Prozedur | Explizites SQL verwenden. Beispiel: |
| Verarbeitung einzelner Zeilen der Ergebnisliste über eine SQL-Anweisung SELECT | EGL-Befehl open zum Öffnen der Ergebnisliste verwenden und
anschließend eine Schleife mit einer der folgenden Anweisungen auslösen:
|
| Programmatic Paging für Onlinesuchvorgänge | Assistenten für die Datenzugriffsanwendung verwenden. |
| Hinzufügen von Daten zur SQL-Tabelle | Tabelleneditor in der Datenperspektive der Workbench verwenden. |
| Gültigkeitsprüfung von SQL-Anweisungen | Im EGL-Editor 'Validate SQL' aus dem Kontextmenü auswählen. |
| Interactive SQL mit dem SQL-Editor in der Datenperspektive der Workbench ausführen. |
Ergebnismengenverarbeitung
- Deklarieren und öffnen Sie einen Cursor, indem Sie eine EGL-Anweisung open mit der Option forUpdate ausführen. Mit dieser Option werden die ausgewählten Zeilen für nachfolgende Aktualisierungen oder Löschvorgänge gesperrt.
- Rufen Sie eine Zeile durch Ausführung der EGL-Anweisung get next ab.
- Führen Sie in einer forEach-Schleife die folgenden Aktionen aus:
- Rufen Sie Daten aus der Ergebnisliste für die Hostvariablen ab. Eine Hostvariable ist eine Variable in einer SQL-Anweisung, deren Name mit einer Variablen in der Hostprogrammiersprache (in diesem Fall enthält EGL die SQL-Anweisungen) übereinstimmt, plus einem zusätzlichen Doppelpunkt (:) als Anfangszeichen.
- Aktualisieren oder löschen Sie die Zeile durch Ausführung einer EGL-Anweisung replace oder delete.
- Rufen Sie eine weitere Zeile durch Ausführung der EGL-Anweisung get next ab.
- Führen Sie die Funktion commit() aus, um die Änderungen festzuschreiben.
Die Anweisungen, die den Cursor öffnen und die Zeilen dieses Cursors bearbeiten, stehen über eine Ergebnismengen-ID miteinander in Beziehung, die für alle Ergebnismengen-IDs und Programmvariablen innerhalb des Programms eindeutig sein muss. Diese ID wird in der Anweisung open angegeben, die den Cursor öffnet, und sie wird in der Anweisung forEach referenziert, die die Schleife erstellt. Ferner kann die ID in den Anweisungen get next, delete und replace referenziert werden, die eine einzelne Zeile betreffen, sowie in der Anweisung close, die den Cursor schließt.
try
open selectEmp forUpdate for emp;
onException(sqlx SqlException)
myErrorHandler(sqlx); // exits program
end
foreach(emp)
emp.empname = emp.empname :: " " :: "III";
try
replace emp;
onException(sqlx SqlException)
myErrorHandler(sqlx); // exits program
end
end // end while; cursor is closed automatically
// when the last row in the result set is read
sysLib.commit();
Verwenden Sie zum regelmäßigen Festschreiben von Änderungen bei der Verarbeitung einer EGL-Anweisung open (unabhängig davon, ob Sie mit SQL-Datensätzen arbeiten) die Anweisungsoption hold, mit der die Cursorposition nach einer Festschreibung gehalten wird. Wenn ein für CICS bestimmtes Programm jedoch segmentiert ist, hat die Option hold keine Auswirkungen, da eine Umkehrung in einem segmentierten Programm die CICS-Transaktion beendet und das Programm an der Aufbewahrung von Dateien oder Datenbankpositionen hindert.
SQL-Datensätze und ihre Verwendung
add myEmpRecord;
try
add myEmpRecord;
onException(sqlx SqlException)
if (myEmpRecord is unique) // if a table row had the same key
myErrorHandler(sqlx);
end
end
- Definieren Sie einen SQLRecord-Abschnitt und deklarieren Sie die zugehörige Datensatzvariable.
- Schreiben Sie SQL-Anweisungen, die mit dem SQL-Datensatz E/A-Aktivitäten ausführen.
- Übernehmen Sie das Standardverhalten der EGL-Anweisungen (das in den meisten Fällen zu dem gewünschten Ergebnis führt) oder nehmen Sie der Geschäftslogik entsprechende SQL-Änderungen vor.
SQLRecord-Abschnitt und zugehörigen Datensatz definieren
Das Definieren eines SQLRecord-Abschnitts und die Zuordnung der einzelnen Felder zu einer Spalte erfolgt in einer relationalen Tabelle oder Ansicht. EGL kann diese Aktionen automatisch ausführen (siehe SQL-Tabellendaten abrufen).
- Andere SQL-Datensätze. Jeder dieser Datensätze repräsentiert eine Eins-zu-eins-Beziehung zwischen der übergeordneten und der untergeordneten Tabelle.
- Arrays mit SQL-Datensätzen. Jeder dieser Datensätze repräsentiert eine Eins-zu-viele-Beziehung zwischen der übergeordneten und der untergeordneten Tabelle.
Eine Datenbankspalte kann nur durch Felder eines Basiselementtyps repräsentiert werden.
- Die Struktur in den einzelnen SQLRecord-Abschnitten muss flach (ohne Hierarchie) sein.
- Alle Felder müssen Basisfelder sein, jedoch nicht vom Typ BLOB, CLOB oder STRING.
- Keines der Datensatzfelder darf eine Strukturfeld-Feldgruppe (structure-field) sein.
Nach dem Definieren eines SQLRecord-Abschnitts wird eine Datensatzvariable basierend auf diesem Abschnitt deklariert.
SQL-bezogene EGL-Anweisungen
Sie können eine Gruppe von EGL-Anweisungen erstellen, die alle die Datensatzvariable als E/A-Objekt in der Anweisung verwenden. EGL stellt für jede Anweisung eine implizite SQL-Anweisung bereit, die nicht in der Quelle enthalten ist, sondern durch die Kombination von Datensatzvariable und EGL-Anweisung impliziert ist. Beispielsweise fügt eine implizite SQL-Anweisung INSERT im Falle einer EGL-Anweisung add die Werte der Felder in einem Datensatz in die zugeordnete Tabellenspalte ein. Wenn die Datensatzvariable ein Feld enthält, für das keine Tabellenspalte zugeordnet wurde, erstellt EGL die implizite SQL-Anweisung unter der Annahme, dass der Name des Felds dem Namen der Spalte entspricht.
Die folgenden EGL-Anweisungen entsprechen den aufgeführten SQL-Anweisungen:
| EGL-Anweisung | SQL-Anweisung |
|---|---|
| add | INSERT |
| delete | DELETE |
| get, open | SELECT |
| replace | UPDATE |
Implizite SELECT-Anweisungen
Record Employee type sqlRecord
{ tableNames = [["EMPLOYEE"]],
keyItems = ["empnum"] }
empnum decimal(6,0);
empname char(40);
end
myEmpRecord Employee;
get myEmpRecord;
SELECT empnum, empname
FROM EMPLOYEE
WHERE empnum = :empnum
INTO :empnum, :empname
- Dem Wert, den Sie für die Datensatzeigenschaft defaultSelectCondition angegeben haben.
- Einer Beziehung (z. B. eine Gleichheit) von zwei Wertegruppen:
- Namen von Spalten, die die Tabellenschlüssel bilden.
- Werte der Hostvariablen, die die Satzschlüssel darstellen.
Einzelheiten zu impliziten SELECT-Anweisungen finden Sie in den verschiedenen Themen zu Schlüsselwörtern im Handbuch EGL Language Reference.
SQL-Datensätze mit Cursorn
Bei Verwendung von SQL-Datensätzen können Anweisungen zur Cursorverarbeitung unter Verwendung derselben Datensatzvariablen in mehreren EGL-Anweisungen zueinander in Beziehung gesetzt werden. Die Vorgehensweise entspricht dabei weitgehend der Verwendung einer Ergebnismengen-ID. Eine über eine Ergebnismengen-ID angegebene anweisungsübergreifende Beziehung hat jedoch Vorrang vor einer über die Datensatzvariable angegebene Beziehung; in einigen Fällen muss eine Ergebnismengen-ID (resultSetID) angegeben werden.
Darüber hinaus kann für eine bestimmte Datensatzvariable nur ein Cursor geöffnet sein. Wenn eine EGL-Anweisung einen Cursor öffnet, solange ein anderer Cursor für dieselbe Datensatzvariable geöffnet ist, wird der erste Cursor automatisch vom generierten Code geschlossen.
Anpassung von SQL-Anweisungen
- Übernehmen Sie die implizite SQL-Anweisung. In diesem Fall haben Änderungen des SQLRecord-Abschnitts Auswirkungen auf die SQL-Anweisungen, die zur Laufzeit verwendet werden. Wenn Sie beispielsweise später angeben, dass ein anderes Feld als Schlüssel für den SQL-Datensatz verwendet werden soll, ändert EGL die implizite Anweisung SELECT in jeder Cursordeklaration, die auf diesem SQLRecord-Abschnitt basiert.
- Geben Sie an, dass die SQL-Anweisung explizit sein soll. EGL kann die implizite SQL-Anweisung
in Ihren Code einfügen, sodass Sie diese ändern können. In diesem Fall sind die Details dieser SQL-Anweisung
vom SQLRecord-Abschnitt getrennt; nachfolgende Änderungen des SQLRecord-Abschnitts haben keine Auswirkungen auf die
SQL-Anweisung, die zur Laufzeit verwendet wird.
Wenn Sie eine explizite SQL-Anweisung aus der Quelle entfernen, ist die implizite SQL-Anweisung (sofern vorhanden) bei der Generierung erneut verfügbar.
Beispiel für die Verwendung eines Datensatzes in einem Datensatz
DataItem DeptNo { column = "deptNo" } end
Record Dept type SQLRecord
deptNo DeptNo;
managerID CHAR(6);
employees Employee[];
end
Record Employee type SQLRecord
employeeID CHAR(6);
empDeptNo DeptNo;
end
Function getDeptEmployees(myDeptRecord Dept)
get myDeptRecord.employees usingKeys myDeptRecord.deptNo;
end
Test und Einstellung für Nullwerte
Record Employee type SQLRecord
employeeID CHAR(6);
empDeptNo INT?;
end
if (myEmpRecord.empDeptNo == null)
...
end
myEmpRecord.empDeptNo = null;
set myEmpRecord.empDeptNo empty;
Kompatibilität
| Plattform | Problem |
|---|---|
| CICS für z/OS, z/OS-Stapelbetrieb, iSeriesC | Der generierte Code kann direkt auf DB2 UDB zugreifen. |
| AIX, HP-UX, iSeriesJ, Linux, Solaris, z/OS UNIX System Services, Windows 2000/NT/XP | JDBC bietet Zugriff auf DB2 UDB, Oracle, Informix und Microsoft SQL Server. |