Natural-Statements und Systemvariablen benutzen

#### Search Results

Search

# Natural-Statements und Systemvariablen benutzen

Dieses Kapitel behandelt besondere Aspekte, die zu berücksichtigen sind, wenn native Natural-DML-Statements und Natural-Systemvariablen zusammen mit Natural-SQL-Statements und Db2 verwendet werden.

Es handelt sich um eine Übersicht über Informationen, die in der Natural-Statements- bzw. -Systemvariablen-Dokumentation ausführlich vorhanden sind.

Eine Erklärung der Symbole, die in diesem Abschnitt zur Darstellung der Syntax von Natural-Statements verwendet werden, finden Sie unter Syntax-Symbole in der Natural-Statements-Dokumentation.

Informationen zur Protokollierung der in einem Natural-Programm enthaltenen SQL-Statements finden Sie unter

DBLOG Trace-Bildschirm für SQL-Statements in der Debugger und Dienstprogramme (Utilities) -Dokumentation.

In diesem Kapitel werden die folgenden Themen behandelt:

- Besondere Aspekte der speziellen Db2-Register

- Verwendung von nativen Natural DML-Statements

- Verwendung von Natural-SQL-Statements

- Verwendung von Natural-Systemvariablen

- Verarbeitung mehrerer Zeilen

- Fehlerbehandlung

## Besondere Aspekte der speziellen Db2-Register

Natural for Db2 aktualisiert die folgenden speziellen Db2-Registerr automatisch auf die Werte, die für die zuletzt ausgeführte Transaktion galten.

- `CURRENT SQLID`

- `CURRENT SCHEMA`

- `CURRENT PATH`

- `CURRENT PACKAGE PATH`

Die Inhalte der folgenden Db2-Spezialregister aktualisiert Natural for Db2 nur dann automatisch auf die Werte, die für die zuletzt ausgeführte Transaktion galten, wenn der Parameter `REFRESH=ON` gesetzt ist.

- `CURRENT PACKAGESET`

- `CURRENT SERVER`

Diese speziellen Register werden unabhängig davon aufgefrischt, ob die zuvor ausgeführte Transaktion rückgängig gemacht (Rollback) oder festgeschrieben (Commit) wurde.

Alle anderen speziellen Register werden von Natural for Db2 nicht implizit beeinflusst.

## Verwendung von nativen Natural DML-Statements

Dieser Abschnitt fasst bestimmte Punkte zusammen, die Sie beachten müssen, wenn Sie Natural-DML-Statements mit Db2 benutzen. Alle Natural-Statements, die in diesem Abschnitt nicht erwähnt werden, können ohne Einschränkung mit Db2 verwendet werden.

Eine Übersicht über die Natural-DML- und SQL-Statements finden Sie im Abschnitt Datenbankzugriffe und Datenbankänderungen in der Natural-Statements-Dokumentation.

Im Folgenden finden Sie Informationen zu den folgenden Natural-DML-Statements:

- BACKOUT TRANSACTION

- DELETE

- END TRANSACTION

- FIND

- HISTOGRAM

- READ

- STORE

- UPDATE

### BACKOUT TRANSACTION

Das native Natural DML-Statement `BACKOUT TRANSACTION` macht alle Datenbanktransaktionen rückgängig, die seit dem Beginn der letzten logischen Transaktion vorgenommen wurden. Logische Transaktionen können entweder nach dem Beginn einer Sitzung oder nach der letzten `SYNCPOINT`-, `END TRANSACTION`- oder `BACKOUT TRANSACTION`-Statement beginnen.

Wie das Statement umgesetzt wird und welches Kommando tatsächlich abgesetzt wird, hängt von der TP-Monitor-Umgebung ab:

- Wenn dieses Kommando innerhalb einer Natural Stored Procedure oder Natural User-Defined Function (UDF) ausgeführt wird, führt Natural for Db2 die zugrunde liegende Rollback-Operation aus. Dadurch wird der Aufrufer in einen Must-Rollback-Zustand versetzt. Wenn dieses Kommando innerhalb einer Natural-Stored-Procedure oder einer UDF für Natural-Fehlerverarbeitung (implizites `ROLLBACK`) ausgeführt wird, führt Natural for Db2 die zugrunde liegende Rollback-Operation nicht aus, so dass der Aufrufer den ursprünglichen Natural-Fehler erhalten kann.

- Unter CICS wird das Statement `BACKOUT TRANSACTION` in ein `EXEC CICS ROLLBACK`-Kommando übersetzt. Im Pseudo-Conversational Mode werden jedoch nur die Änderungen rückgängig gemacht, die seit der letzten Terminal-E/A an der Datenbank vorgenommen wurden. Dies liegt an der CICS-spezifischen Transaktionsverarbeitung, siehe Natural for Db2 unter CICS.

  Anmerkung
  Beachten Sie, dass Natural bei Terminaleingaben in Datenbankschleifen in den Conversational Mode wechselt, wenn kein File Server verwendet wird.

- Im Batch-Modus und unter TSO wird das `BACKOUT TRANSACTION`-Statement in ein SQL `ROLLBACK`-Kommando übersetzt.

  Anmerkung
  In einer `DSNMTV01`-Umgebung wird das `BACKOUT TRANSACTION`-Statement ignoriert, wenn der verwendete PSB ohne die Option `CMPAT=YES` generiert wurde.

- Unter IMS TM wird das `BACKOUT TRANSACTION`-Statement in ein IMS-Rollback-Kommando (`ROLB`) übersetzt. Es werden jedoch nur die Änderungen an der Datenbank rückgängig gemacht, die seit der letzten Terminal-E/A vorgenommen wurden. Dies liegt an der IMS TM-spezifischen Transaktionsverarbeitung, siehe Natural for Db2 unter IMS TM.

Da alle Cursors geschlossen werden, wenn eine logische Arbeitseinheit endet, darf ein `BACKOUT TRANSACTION`-Statement nicht innerhalb einer Datenbankschleife stehen, sondern muss außerhalb einer solchen Schleife oder nach der äußersten Schleife von geschachtelten Schleifen stehen.

Wenn ein externes Programm, das in einer anderen Standardprogrammiersprache geschrieben wurde, von einem Natural-Programm aufgerufen wird, darf dieses externe Programm kein eigenes `ROLLBACK`-Kommando enthalten, wenn das Natural-Programm ebenfalls Datenbankaufrufe tätigt. Das aufrufende Natural-Programm muss das `BACKOUT TRANSACTION`-Statement für das externe Programm absetzen.

Versucht ein Programm, Änderungen zurückzunehmen (Backout), die bereits festgeschrieben (Commit) wurden, z.B. durch eine Terminal-E/A, so wird eine entsprechende Natural-Fehlermeldung (NAT3711) zurückgegeben.

### DELETE

Das native Natural DML-Statement `DELETE` wird verwendet, um eine Zeile aus einer Tabelle zu löschen, die mit einem vorangegangenen `FIND`-, `READ`- oder `SELECT`-Statement gelesen wurde. Es entspricht dem SQL-Statement `DELETE WHERE CURRENT OF cursor-name`, was bedeutet, dass nur die zuletzt gelesene Zeile gelöscht werden kann.

Beispiel:

    FIND EMPLOYEES WITH NAME = 'SMITH'
         AND FIRST_NAME = 'ROGER'
    DELETE

Natural übersetzt die obigen Natural-Statements in SQL und vergibt einen Cursornamen (z.B. `CURSOR1`) wie folgt:

    DECLARE CURSOR1 CURSOR FOR
    SELECT FROM EMPLOYEES
     WHERE NAME = 'SMITH' AND FIRST_NAME = 'ROGER' FOR UPDATE OF NAME
    DELETE FROM EMPLOYEES
     WHERE CURRENT OF CURSOR1

Sowohl das `SELECT`- als auch das `DELETE`-Statement beziehen sich auf denselben Cursor.

Natural übersetzt ein natives Natural-DML-`DELETE`-Statement in ein Natural-SQL-`DELETE`-Statement auf die gleiche Weise, wie es ein natives Natural-DML-`FIND`-Statement in ein Natural-SQL-SELECT-Statement übersetzt.

Eine mit einem `FIND SORTED BY`-Statement gelesene Zeile kann aufgrund der beim `FIND`-Statement beschriebenen Db2-Einschränkungen nicht gelöscht werden. Eine mit `READ LOGICAL` gelesene Zeile kann ebenfalls nicht gelöscht werden.

#### DELETE bei Verwendung des File Servers

Wenn eine auf den File Server ausgelagerte Zeile gelöscht werden soll, liest Natural automatisch die ursprüngliche Zeile aus der Datenbank ein und vergleicht sie mit ihrem auf dem File Server gespeicherten Abbild. Wenn die ursprüngliche Zeile in der Zwischenzeit nicht geändert wurde, wird die `DELETE`-Operation durchgeführt. Bei der nächsten Terminal-E/A wird die Transaktion beendet, und die Zeile wird aus der aktuellen Datenbank gelöscht.

Wenn die `DELETE`-Operation auf einen scrollbaren Cursor wirkt, wird die Zeile auf dem File Server als "freier Datenbereich durch Löschen" (`DELETE`-Hole) markiert und aus der Basistabelle gelöscht.

Wird jedoch eine Änderung festgestellt, so wird die Zeile nicht gelöscht und Natural gibt die Fehlermeldung NAT3703 für nicht scrollbare Cursor aus.

Wenn das `DELETE` auf einen scrollbaren Cursor wirkt, simuliert Natural for Db2 zwecks Konformität mit Db2 den SQLCODE -224 `THE RESULT TABLE DOES NOT AGREE WITH THE BASE TABLE USING`.

Wenn das `DELETE` auf einen scrollbaren Cursor wirkt und die Zeile zu einem "freien Datenbereich durch Löschen" (`DELETE`-Hole) geworden ist, simuliert Natural for Db2 den SQLCODE -222 `AN UPDATE OR DELETE OPERATION WAS ATTEMPTED AGAINST A HOLE`.

Da ein `DELETE`-Statement erfordert, dass Natural eine einzelne Zeile erneut liest, muss ein eindeutiger Index für die entsprechende Tabelle vorhanden sein. Alle Spalten, die den eindeutigen Index bilden, müssen Teil der entsprechenden Natural-View sein.

### END TRANSACTION

Das native DML-Statement `END TRANSACTION` zeigt das Ende einer logischen Transaktion an und gibt alle während der Transaktion gesperrten Db2-Daten frei. Alle Datenänderungen werden übergeben (Commit) und dauerhaft gemacht.

Wie das Statement übersetzt wird und welches Kommando tatsächlich ausgegeben wird, hängt von der TP-Monitor-Umgebung ab:

- Wenn dieses Kommando aus einer Natural Stored Procedure oder einer User Defined Function (UDF) ausgeführt wird, führt Natural for Db2 die zugrunde liegende Commit-Operation nicht aus. Dadurch kann die Stored Procedure oder UDF Änderungen (Updates) gegen Nicht-Db2-Datenbanken vornehmen (Commit).

- Unter CICS wird das `END TRANSACTION`-Statement in ein `EXEC CICS SYNCPOINT`-Kommando übersetzt. Wenn der File Server verwendet wird, wird nach jeder Terminal-E/A ein implizites Transaktionsende (End of Transaction) abgesetzt. Dies liegt an der CICS-spezifischen Transaktionsverarbeitung im Pseudo-Conversational Mode, siehe Natural for Db2 unter CICS.

- Im Batch-Modus und unter TSO wird das `END TRANSACTION`-Statement in ein SQL-Kommando `COMMIT WORK` übersetzt.

  Anmerkung
  In einer `DSNMTV01`-Umgebung wird das `END TRANSACTION`-Statement ignoriert, wenn der verwendete PSB ohne die Option `CMPAT=YES` erzeugt wurde.

- Unter IMS TM wird das `END TRANSACTION`-Statement nicht in einen IMS CHKP-Aufruf übersetzt, sondern ignoriert. Aufgrund der IMS TM-spezifischen Transaktionsverarbeitung (siehe Natural for Db2 unter IMS TM) wird nach jeder Terminal-E/A ein implizites Transaktionsende (End of Transaction) ausgegeben.

Außer in Kombination mit der `WITH HOLD`-Klausel (siehe `SELECT - SQL` unter Verwendung von Natural SQL-Statements) darf ein `END TRANSACTION`-Statement nicht innerhalb einer Datenbankschleife stehen, da alle Cursor geschlossen werden, wenn eine logische Arbeitseinheit endet. Stattdessen muss sie außerhalb einer solchen Schleife bzw. bei geschachtelten Schleifen nach der äußersten Schleife stehen.

Wird ein externes Programm, das in einer anderen Standardprogrammiersprache geschrieben wurde, von einem Natural-Programm aufgerufen, darf dieses externe Programm kein eigenes `COMMIT`-Kommando enthalten, wenn das Natural-Programm ebenfalls Datenbankaufrufe tätigt. Das aufrufende Natural-Programm muss das `END TRANSACTION`-Statement für das externe Programm absetzen.

Anmerkung
Bei Db2 kann das `END TRANSACTION`-Statement nicht verwendet werden, um Transaktionsdaten zu speichern.

### FIND

Das native Natural-DML-Statement `FIND` entspricht dem Natural SQL-Statement `SELECT`.

Beispiel:

Native Natural-DML-Statements:

    FIND EMPLOYEES WITH NAME = 'BLACKMORE'
       AND AGE EQ 20 THRU 40
    OBTAIN PERSONNEL_ID NAME AGE

Äquivalentes Natural-SQL-Statement:

    SELECT PERSONNEL_ID, NAME, AGE
      FROM EMPLOYEES
        WHERE NAME = 'BLACKMORE'
          AND AGE BETWEEN 20 AND 40

Natural übersetzt intern ein `FIND`-Statement in ein SQL-`SELECT`-Statement. Siehe Beschreibung in Verarbeitung von SQL-Statements, die von Natural ausgegeben werden im Abschnitt Interne Behandlung dynamischer Statements. Das `SELECT`-Statement wird von einem `OPEN CURSOR`-Statement, gefolgt von einem `FETCH`-Kommando, ausgeführt. Das `FETCH`-Kommando wird so oft ausgeführt, bis entweder alle Sätze gelesen wurden oder der Programmablauf die `FIND`-Verarbeitungsschleife verlässt. Ein `CLOSE CURSOR`-Kommando beendet die `SELECT`-Verarbeitung.

Die `WITH`-Klausel eines `FIND`-Statements wird in die `WHERE`-Klausel des `SELECT`-Statements umgesetzt. Das Basissuchkriterium für eine Db2-Tabelle kann auf die gleiche Weise wie für eine Adabas-Datei angegeben werden. Das bedeutet, dass nur Datenbankfelder, die als Deskriptoren definiert sind, zum Aufbau von Basissuchkriterien verwendet werden können und dass Deskriptoren nicht mit anderen Feldern der Natural-View (d.h. Datenbankfeldern) verglichen werden können, sondern nur mit Programmvariablen oder Konstanten.

Anmerkung
Da jedes Datenbankfeld (Spalte/Column) einer Db2-Tabelle für die Suche verwendet werden kann, kann ein beliebiges Datenbankfeld als Deskriptor in einem Natural-DDM definiert werden.

Die `WHERE`-Klausel des `FIND`-Statements wird von Natural ausgewertet, nachdem die Zeilen über die `WITH`-Klausel ausgewählt worden sind. Innerhalb der `WHERE`-Klausel können Nicht-Deskriptoren verwendet werden und Datenbankfelder können mit anderen Datenbankfeldern verglichen werden.

Anmerkung
Db2 kennt keine Sub-, Super- oder phonetischen Deskriptoren.

Ein `FIND NUMBER`-Statement wird in ein `SELECT`-Statement mit einer `COUNT(*)`-Klausel übersetzt. Die Anzahl der gefundenen Zeilen wird in der Natural-Systemvariablen `*NUMBER` zurückgegeben. Beschreibung siehe Natural-Systemvariablen-Dokumentation.

Das `FIND UNIQUE`-Statement kann verwendet werden, um sicherzustellen, dass nur ein Datensatz für die Verarbeitung ausgewählt wird. Wenn das `FIND UNIQUE`-Statement von einem `UPDATE`-Statement referenziert wird, wird eine `UPDATE`-Operation ohne Cursor (Searched) anstelle einer cursororientierten (Positioned) `UPDATE`-Operation generiert. Daher können Sie es verwenden, wenn Sie einen Db2-Primärschlüssel aktualisieren möchten. Es wird jedoch empfohlen, zur Aktualisierung eines Primärschlüssels das Natural SQL Searched `UPDATE`-Statement zu verwenden.

Im statischen Modus werden die Statements `FIND NUMBER` und `FIND UNIQUE` in ein `SELECT SINGLE`-Statement übersetzt. Siehe Abschnitt Verwendung von Natural SQL-Statements.

Das `FIND FIRST`-Statement kann nicht verwendet werden. Die Klauseln `PASSWORD`, `CIPHER`, `COUPLED` und `RETAIN` können ebenfalls nicht verwendet werden.

Die `SORTED BY`-Klausel eines `FIND`-Statements wird in die SQL-Klausel `SELECT ... ORDER BY` übersetzt, die auf das Suchkriterium folgt. Da dies eine schreibgeschützte Ergebnistabelle ergibt, kann eine mit einem `FIND`-Statement gelesene Zeile, die eine `SORTED BY`-Klausel enthält, nicht aktualisiert oder gelöscht werden.

Bei der Installation kann eine Grenze für die Tiefe der verschachtelten Datenbankschleifen festgelegt werden. Wird diese Grenze überschritten, so wird eine Natural-Fehlermeldung ausgegeben.

Anmerkungen:

1. Wenn eine Verarbeitungsgrenze als konstante Ganzzahl angegeben wird, z. B. `FIND (5)`, wird der Grenzwert in eine `FETCH FIRST integer ROWS ONLY`-Klausel im generierten SQL-String übersetzt.
2. Natural for Db2 unterstützt die Verarbeitung mehrerer Zeilen in Db2 im Rahmen der `MULTIFETCH`-Klausel des `FIND`-Statements.

#### FIND bei Verwendung des File Servers

Hinsichtlich der Nutzung des File Servers gibt es keine programmtechnischen Einschränkungen bei den Auswahl-Statements. Es ist jedoch empfehlenswert, sich mit der Funktionalität vertraut zu machen, um die Leistungsfähigkeit und den Platzbedarf des File Servers zu berücksichtigen.

### HISTOGRAM

Das Natural DML-Statement `HISTOGRAM` gibt die Anzahl der Zeilen in einer Tabelle zurück, die in einer bestimmten Spalte den gleichen Wert haben. Die Anzahl der Zeilen wird in der Natural-Systemvariablen `*NUMBER` zurückgegeben. Siehe Natural-Systemvariablen-Dokumentation.

Beispiel:

Native Natural-DML-Statements:

    HISTOGRAM EMPLOYEES FOR AGE
    OBTAIN AGE

Äquivalentes Natural-SQL-Statement:

    SELECT COUNT(*), AGE FROM EMPLOYEES
      WHERE AGE > -999
      GROUP BY AGE
      ORDER BY AGE

Natural übersetzt das `HISTOGRAM`-Statement in ein SQL-`SELECT`-Statement, d.h. der Kontrollfluss ist ähnlich wie beim `FIND`-Statement beschrieben.

Anmerkung
Mit dem Universal Database Server for z/OS Version 8 unterstützt Natural for Db2 die Verarbeitung mehrerer Zeilen in Db2 im Rahmen der `MULTIFETCH`-Klausel des `HISTOGRAM`-Statements.

### READ

Das native Natural-DML-Statement `READ` kann auch für den Zugriff auf Db2-Tabellen verwendet werden. Natural übersetzt ein `READ`-Statement in ein SQL `SELECT`-Statement.

`READ PHYSICAL` und `READ LOGICAL` können verwendet werden. `READ BY ISN` kann jedoch nicht verwendet werden, da es keine Db2-Entsprechung zu Adabas-ISNs gibt. Die Klauseln `PASSWORD` und `CIPHER` können auch nicht verwendet werden.

Da ein `READ LOGICAL`-Statement in ein `SELECT ... ORDER BY`-Statement übersetzt wird, das eine schreibgeschützte Tabelle erzeugt, kann eine mit einem `READ LOGICAL`-Statement gelesene Zeile nicht geändert oder gelöscht werden (siehe Beispiel 1). Der Startwert kann nur eine Konstante oder eine Programmvariable sein; ein anderes Feld der Natural-Ansicht (d.h. ein Datenbankfeld) kann nicht verwendet werden.

Ein `READ PHYSICAL`-Statement wird in ein `SELECT`-Statement ohne `ORDER BY`-Klausel übersetzt und kann daher aktualisiert oder gelöscht werden (siehe Beispiel 2).

Beispiel 1:

Natives Natural-DML-Statement:

    READ PERSONNEL BY NAME
    OBTAIN NAME FIRSTNAME DATEOFBIRTH

Äquivalentes Natural-SQL-Statement:

    SELECT NAME, FIRSTNAME, DATEOFBIRTH FROM PERSONNEL
      WHERE NAME >= ' '
        ORDER BY NAME

Beispiel 2:

Native Natural-DML-Statements:

    READ PERSONNEL PHYSICAL
    OBTAIN NAME

Äquivalentes Natural-SQL-Statement:

    SELECT NAME FROM PERSONNEL

Wenn das `READ`-Statement eine `WHERE`-Klausel enthält, wird diese Klausel vom Natural-Prozessor ausgewertet, nachdem die Zeilen gemäß dem (den) im Suchkriterium angegebenen Deskriptorwert(en) ausgewählt wurden.

#### Verarbeitungsgrenze

Wenn eine Verarbeitungsgrenze als konstante Ganzzahl, z.B. `READ (5)`, im generierten SQL-String angegeben ist, wird der Wert, der die Grenze definiert, in die Klausel übersetzt:

`FETCH FIRST` integer `ROWS ONLY`

#### Cursors für Db2-Klauseln

Natural for Db2 verwendet insensitive scrollbare Cursors, um das folgende `READ` `READ`-Statement zu verarbeiten:

`READ` `.. [IN] [LOGICAL] VARIABLE/DYNAMIC` operand5 `[SEQUENCE]`

Natural for Db2 verwendet insensitive scrollbare Cursors, um das folgende `READ`-Statement zu verarbeiten. Wenn es sich um ein Positioned `UPDATE`- oder Positioned `DELETE`-Statement handelt, verwendet Natural for Db2 insensitive statische Cursors.

`READ .. [IN] [PHYSICAL] DESCENDING/VARIABLE/DYNAMIC` operand5 `[SEQUENCE]`

`operand5`

Der Wert A wird in einen `FETCH FIRST/NEXT`-Db2-Zugriff und der Wert `D` in einen `FETCH LAST/PRIOR`-Db2-Zugriff übersetzt.

Anmerkung
Natural for Db2 unterstützt die Db2-Verarbeitung mehrerer Zeilen im Rahmen der `MULTIFETCH`-Klausel im `READ`-Statement.

#### READ bei Verwendung des File Servers

Hinsichtlich der Verwendung des File Servers gibt es keine programmtechnischen Einschränkungen bei den Auswahl-Statements. Es ist jedoch empfehlenswert, sich mit der Funktionalität unter Berücksichtigung von Performance und Platzbedarf des File Servers vertraut zu machen.

### STORE

Das Native Natural-DML-Statement `STORE` wird verwendet, um eine Zeile zu einer Db2-Tabelle hinzuzufügen. Das STORE-Statement entspricht dem SQL- Statement `INSERT`.

Beispiel:

Natives Natural-DML-Statement:

    STORE RECORD IN EMPLOYEES
      WITH PERSONNEL_ID = '2112'
           NAME         = 'LIFESON'
           FIRST_NAME   = 'ALEX'

Äquivalentes Natural SQL-Statement:

    INSERT INTO EMPLOYEES (PERSONNEL_ID, NAME, FIRST_NAME)
      VALUES ('2112', 'LIFESON', 'ALEX')

Die Klauseln `PASSWORD`, `CIPHER` und `USING/GIVING NUMBER` des `STORE`-Statements können nicht verwendet werden.

### UPDATE

Das native Natural-DML-Statement `UPDATE` aktualisiert eine Zeile in einer Db2-Tabelle, die mit einem vorangegangenen `FIND`, `READ` oder `SELECT`-Statement gelesen wurde. Sie entspricht dem SQL-Statement `UPDATE WHERE CURRENT OF cursor-name` (Positioned `UPDATE`), was bedeutet, dass nur die zuletzt gelesene Zeile aktualisiert werden kann.

#### UPDATE bei Verwendung des File Servers

Wenn eine auf den File Server ausgelagerte Zeile aktualisiert werden soll, liest Natural automatisch die ursprüngliche Zeile aus der Datenbank ein und vergleicht sie mit ihrem auf dem File Server gespeicherten Abbild. Wenn die ursprüngliche Zeile in der Zwischenzeit nicht geändert wurde, wird die `UPDATE`-Operation durchgeführt. Bei der nächsten Terminal-E/A wird die Transaktion beendet und die Zeile endgültig in der Datenbank aktualisiert.

Wenn die `UPDATE`-Operation auf einen scrollbaren Cursor wirkt, werden die Zeile auf dem File Server und die Zeile in der Basistabelle aktualisiert. Erfüllt die Zeile nach der Aktualisierung nicht mehr die Suchkriterien des zugehörigen `SELECT`-Statements, wird die Zeile auf dem File Server als "freier Datenbereich durch Aktualisieren" (`UPDATE`-Hole) markiert.

Wird jedoch eine Änderung festgestellt, wird die Zeile nicht aktualisiert und Natural gibt die Fehlermeldung NAT3703 für nicht scrollbare Cursor aus.

Wenn das `UPDATE` auf einen scrollbaren Cursor wirkt, simuliert Natural for Db2 zwecks Konformität mit Db2 den SQLCODE -224 THE RESULT TABLE DOES NOT AGREE WITH THE BASE TABLE USING.

Wenn das `UPDATE` auf einen scrollbaren Cursor wirkt und die Zeile ein "freier Datenbereich durch Aktualisieren" (`UPDATE`-Hole) geworden ist, simuliert Natural for Db2 den SQLCODE -222 AN UPDATE OR DELETE OPERATION WAS ATTEMPTED AGAINST A HOLE.

Da ein `UPDATE-`Statement das erneute Lesen einer einzelnen Zeile durch Natural erfordert, muss ein eindeutiger Index für diese Tabelle vorhanden sein. Alle Spalten, die den eindeutigen Index umfassen, müssen Teil der entsprechenden Natural-View sein.

#### UPDATE mit FIND/READ

Wie beim nativen Natural-DML-Statement `FIND` beschrieben, übersetzt Natural ein `FIND`-Statement in ein SQL `SELECT`-Statement. Wenn ein Natural-Programm ein DML `UPDATE`-Statement enthält, wird dieses Statement in ein SQL `UPDATE`-Statement übersetzt und dem `SELECT`-Statement eine `FOR UPDATE OF`-Klausel hinzugefügt.

Beispiel:

    FIND EMPLOYEES WITH SALARY < 5000
      ASSIGN SALARY = 6000
      UPDATE

Natural übersetzt die obigen Natural-Anweisungen in SQL und vergibt einen Cursornamen (z. B. `CURSOR1`) wie folgt:

    DECLARE CURSOR1 CURSOR FOR
    SELECT SALARY FROM EMPLOYEES WHERE SALARY < 5000
      FOR UPDATE OF SALARY
    UPDATE EMPLOYEES SET SALARY = 6000
      WHERE CURRENT OF CURSOR1

Sowohl das `SELECT`- als auch das `UPDATE`-Statement beziehen sich auf denselben Cursor.

Aufgrund der Db2-Logik kann eine Spalte (ein Feld) nur dann aktualisiert werden, wenn sie in der `FOR UPDATE OF`-Klausel enthalten ist. Andernfalls wird das Aktualisieren dieser Spalte (dieses Feldes) abgelehnt. Natural nimmt automatisch alle Spalten (Felder) in die `FOR UPDATE OF`-Klausel auf, die an beliebiger Stelle im Natural-Programm geändert wurden oder die als Teil einer Natural-Maske (Map) Eingabefelder sind.

Eine Db2-Spalte wird jedoch nicht aktualisiert, wenn die Spalte (das Feld) im Natural-DDM als "nicht aktualisierbar" gekennzeichnet ist. Solche Spalten (Felder) werden ohne Warnung oder Fehlermeldung aus der `FOR UPDATE OF`-Liste entfernt. Die in der `FOR UPDATE OF`-Liste enthaltenen Spalten (Felder) können mit dem Kommando `LISTSQL` überprüft werden.

Der Adabas-Kurzname im Natural DDM bestimmt, ob eine Spalte (ein Feld) aktualisiert werden kann.

Die folgende Tabelle zeigt, welche Bereiche gelten:

Kurzbezeichnungsbereich | Feldtyp
--- | ---
AA - N9 | Nicht-Schlüsselfeld, das aktualisiert werden kann.
Aa - Nz | Nicht-Schlüsselfeld, das aktualisiert werden kann.
OA - O9 | Primärschlüsselfeld.
PA - P9 | Aufsteigendes Schlüsselfeld, das aktualisiert werden kann.
QA - Q9 | Absteigendes Schlüsselfeld, das aktualisiert werden kann.
RA - X9 | Nicht-Schlüsselfeld, das nicht aktualisiert werden kann.
Ra - Xz | Nicht-Schlüsselfeld, das nicht aktualisiert werden kann.
YA - Y9 | Aufsteigendes Schlüsselfeld, das nicht aktualisiert werden kann.
ZA - Z9 | Absteigendes Schlüsselfeld, das nicht aktualisiert werden kann.
1A - 9Z | Nicht-Schlüsselfeld, das nicht aktualisiert werden kann.
1a - 9z | Nicht-Schlüsselfeld, das nicht aktualisiert werden kann.

Beachten Sie, dass ein Primärschlüsselfeld niemals Teil einer `FOR UPDATE OF`-Liste ist. Ein Primarschlüsselfeld kann nur mit einer `UPDATE`-Operation ohne Cursor aktualisiert werden (siehe auch das Natural-SQL-`UPDATE`-Statement im Abschnitt Verwendung von Natural SQL Statements.

Beachten Sie, dass ein Primärschlüsselfeld niemals Teil einer `FOR UPDATE OF`-Liste ist, außer wenn die Compiler-Option `DB2PKYU` auf `ON` gesetzt ist. Wenn `DB2PKYU` auf `OFF` gesetzt ist, was der Standardwert ist, können Sie ein Primärschlüsselfeld nur mit einer `UPDATE`-Operation ohne Cursor aktualisieren. Weitere Informationen finden Sie auch unter Natural SQL `UPDATE`-Statement im Abschnitt Verwendung von Natural SQL-Statements.

Eine mit einem `FIND`-Statement gelesene Zeile, die eine `SORTED BY`-Klausel enthält, kann nicht aktualisiert werden (aufgrund von Db2-Einschränkungen, wie bei dem `FIND`-Statement beschrieben). Eine mit einem `READ LOGICAL`-Statement gelesene Zeile kann ebenfalls nicht aktualisiert werden (wie bei dem `READ`-Statement beschrieben).

Wenn eine Spalte aktualisiert werden soll, die als Array redefiniert ist, wird dringend empfohlen, die gesamte Spalte zu aktualisieren und nicht einzelne Ausprägungen. Andernfalls sind die Ergebnisse nicht vorhersehbar. Dazu können Sie im Reporting Mode das Statement `OBTAIN` verwenden, das auf alle Feldausprägungen in der zu aktualisierenden Spalte angewendet werden muss. Im Structured Mode hingegen müssen alle diese Ausprägungen in der entsprechenden Natural-View definiert sein.

Die durch ein `UPDATE`-Statement gesperrten Daten werden freigegeben, wenn ein Statement `END TRANSACTION` (`COMMIT WORK`) oder `BACKOUT TRANSACTION` (`ROLLBACK WORK`) vom Programm ausgeführt wird.

Anmerkung
Wird in einem Natural-Programm ein Längen-Indikatorfeld oder ein `NULL`-Indikatorfeld aktualisiert, ohne dass das Feld (die Spalte), auf das es sich bezieht, aktualisiert wird, so wird die Aktualisierung der Spalte für Db2 nicht generiert und es erfolgt somit keine Aktualisierung.

#### UPDATE bei SELECT

Generell kann das native Natural-DML-Statement `UPDATE` sowohl im Structured als auch im Reporting Mode verwendet werden. Nach einem `SELECT`-Statement ist jedoch nur die für den Natural Structured Mode definierte Syntax zulässig:

`UPDATE` [`RECORD`] [`IN`] [`STATEMENT`] [(r)]

Dies liegt daran, dass das native Natural-DML-Statement `UPDATE` in Kombination mit dem `SELECT`-Statement nur im folgenden speziellen Fall erlaubt ist:

    ...
    SELECT ...
       INTO VIEW view-name
       ...

Es kann also nur eine ganze Natural-View aktualisiert werden, einzelne Spalten (Felder) nicht.

Beispiel:

    DEFINE DATA LOCAL
    01 PERS VIEW OF SQL-PERSONNEL
      02 NAME
      02 AGE
    END-DEFINE

    SELECT *
      INTO VIEW PERS
      FROM SQL-PERSONNEL
      WHERE NAME LIKE 'S%'

        IF NAME = 'SMITH'
          ADD 1 TO AGE
        UPDATE
        END-IF

    END-SELECT
        ...

In Kombination mit dem nativen Natural-DML-Statement `UPDATE` wird jede andere Form des `SELECT`-Statements zurückgewiesen und eine Fehlermeldung zurückgegeben.

Im übrigen kann das native Natural-DML-Statement `UPDATE` mit dem `SELECT`-Statement genauso wie mit dem Natural-Statement `FIND` verwendet werden.

## Verwendung von Natural-SQL-Statements

Dieser Abschnitt behandelt Punkte, die bei der Verwendung von Natural SQL-Statements mit Db2 zu beachten sind. Diese Db2-spezifischen Punkte bestehen zum Teil aus Syntaxerweiterungen, die zum Extended Set der Natural SQL-Syntax gehören. Das Extended Set wird zusätzlich zum Common Set angeboten, um datenbankspezifische Besonderheiten zu unterstützen. Siehe Common Set und Extended Set in der Statements-Dokumentation.

Informationen zur Protokollierung der in einem Natural-Programm enthaltenen SQL-Statements finden Sie unter DBLOG Trace-Bildschirm für SQL-Statements unter DBLOG Utility in der Debugger und Dienstprogramme (Utilities)-Dokumentation.

Nachfolgend finden Sie Informationen zu den folgenden Natural SQL-Statements und zu gemeinsamen syntaktischen Elementen:

- Gemeinsame syntaktische Elemente für Natural SQL-Statements

- CALLDBPROC - SQL

- COMMIT - SQL

- DELETE - SQL

- INSERT - SQL

- MERGE - SQL

- PROCESS SQL

- READ RESULT SET - SQL

- ROLLBACK - SQL

- SELECT - SQL

- UPDATE - SQL

### Gemeinsame syntaktische Elemente für Natural SQL-Statements

Die folgenden gemeinsamen syntaktischen Elemente sind entweder Db2-spezifisch und entsprechen nicht den Standard-SQL-Syntaxdefinitionen (d.h. dem Common Set der Natural SQL Syntax) oder unterliegen Einschränkungen bei der Verwendung mit Db2 (siehe auch Natural-SQL-Statements benutzen in der Natural-Statements-Dokumentation).

Im Folgenden finden Sie Informationen zu den gemeinsamen syntaktischen Elementen:

- atom
- comparison
- factor
- scalar-function
- column-function (aggregate-function)
- scalar-operator
- special-register
- units
- case-expression

#### atom

Ein atom kann entweder ein Parameter (d.h. eine Natural-Programm- oder Host-Variable) oder eine Konstante sein. Bei der dynamischen Ausführung ist die Verwendung von Host-Variablen jedoch durch Db2 eingeschränkt. Weitere Einzelheiten sind in der entsprechenden Db2-Literatur von IBM zu finden.

#### comparison

Die für Db2 spezifischen Vergleichsoperatoren gehören zum Natural SQL Extended Set. Eine Beschreibung finden Sie unter comparison-predicate in Suchbedingungen in der Statements-Dokumentation.

#### factor

Die folgenden Faktoren sind Db2-spezifisch und gehören zum Natural SQL Extended Set:

special-register scalar-function (scalar-expression`, ...`) scalar-expression unit case-expression

#### scalar-function

Eine scalar-function ist eine eingebaute Funktion, die bei der Formulierung von skalaren Berechnungsausdrücken verwendet werden kann. Scalar-functions sind Db2-spezifisch und gehören zum Natural SQL Extended Set.

Die scalar-functions, die Natural for Db2 unterstützt, sind unten in alphabetischer Reihenfolge aufgeführt:

A - H | I - R | S - Z
--- | --- | ---
`ABS` `ABSVAL` `ACOS` `ADD_DAYS` `ADD_MONTHS` `AI_ANALOGY` `AI_SEMANTIC_CLUSTER` `AI_SIMILARITY` `ASIN` `ASCII` `ASCII_CHR` `ASCII_STR` `ATAN` `ATAN2` `ATANH` `BIGINT` `BINARY` `BLOB` `CCSID_ENCODING` `CEIL` `CEILING` `CHAR` `CHARACTER_LENGTH` `CHAR_LENGTH` `CLOB` `COALESCE` `COLLATION_KEY` `COMPARE_DECFLOAT` `CONCAT` `CONTAINS` `COS` `COSH` `DATE` `DAY` `DAYOFMONTH` `DAYOFWEEK` `DAYOFWEEK_ISO` `DAYOFYEAR` `DAYS` `DBCLOB` `DEC` `DECFLOAT` `DECFLOAT_SORTKEY` `DECIMAL` `DECRYPT_BIT` `DECRYPT_CHAR` `DECRYPT_DB` `DECRYPT_DATAKEY_BIT` `DECRYPT_DATAKEY_BIGINT` `DECRYPT_DATAKEY_CLOB` `DECRYPT_DATAKEY_DBCLOB` `DECRYPT_DATAKEY_DECIMAL` `DECRYPT_DATAKEY_INTEGER` `DECRYPT_DATAKEY_VARCHAR` `DECRYPT_DATAKEY_VARGRAPHIC` `DEGREES` `DIFFERENCE` `DIGITS` `DOUBLE` `DOUBLE_PRECISION` `DSN_XMLVALIDATE` `EBCDIC_CHR` `EBCDIC_STR` `ENCRYPT_DATAKEY` `ENCRYPT_TDES` `ENCRYPT` `EXP` `EXTRACT` `FLOAT` `FLOOR` `GRAPHIC` `GENERATE_UNIQUE` `GETHINT` `GETVARIABLE` `GREATEST` `HASH` `HASH_CRC32` `HASH_MD5` `HASH_SHA1` `HASH_SHA256` `HEX` `HOUR` | `IDENTITY_VAL_LOCAL` `IFNULL` `INSERT` `INSTR` `INTEGER` `JULIAN_DAY` `LAST_DAY` `LCASE` `LEAST` `LEFT` `LENGTH` `LN` `LOCATE` `LOCATE_IN_STRING` `LOG` `LOG10` `LOWER` `LPAD` `LTRIM` `MAX` `MICROSECOND` `MIDNIGHT_SECONDS` `MIN` `MINUTE` `MOD` `MONTH` `MONTHS_BETWEEN` `MQPUBLISH` `MQPUBLISHXML` `MQREAD` `MQREADCLOB` `MQREADXML` `MQRECEIVE` `MQRECEIVECLOB` `MQRECEIVEXML` `MQSEND` `MQSENDXML` `MQSENDXMLFILE` `MQSENDXMLFILECLOB` `MQSUBSCRIBE` `MQUNSUBSCRIBE` `MULTIPLY_ALT` `NEXT_DAY` `NORMALIZE_DECFLOAT` `NORMALIZE_STRING` `NULLIF` `OVERLAY` `POSSTR` `POW` `POWER` `QUANTIZE` `QUARTER` `RADIANS` `RAISE_ERROR` `RAND` `RANDOM` `REAL` `REGEXP_COUNT` `REGEXG_INSTR` `REGEXP_LIKE` `REGEXP_REPLACE` `REGEXP_SUBSTR` `REPEAT` `REPLACE` `RID` `RIGHT` `ROUND` `ROUND_TIMESTAMP` `ROWID` `RPAD` `RTRIM` | `SCORE` `SECOND` `SIGN` `SIN` `SINH` `SMALLINT` `SOAPHTTPC` `SOAPHTTPV` `SOAPHTTPNC` `SOAPHTTPNV` `SOUNDEX` `SPACE` `SQRT` `STRIP` `STRLEFT` `STPOS` `STRIGHT` `SUBSTR` `SUBSTRING` `TAN` `TANH` `TIME` `TIMESTAMP` `TIMESTAMPADD` `TIMESTAMP_FORMAT` `TIMESTAMP_ISO` `TIMESTAMP_TZ` `TO_CHAR` `TO_CLOB` `TO_DATE` `TO_NUMBER` `TO_TIMESTAMP` `TOTALORDER` `TRANSLATE` `TRUNC` `TRUNC_TIMESTAMP` `TRUNCATE` `UCASE` `UNICODE` `UNICODE_STR` `UNISTR` `UPPER` `VALUE` `VARBINARY` `VARCHAR` `VARCHAR_FORMAT` `VARGRAPHIC` `WEEK` `WEEK_ISO` `XMLATTRIBUTES` `XMLCONCAT` `XMLCOMMENT` `XMLDOCUMENT` `XMLELEMENT` `XMLFOREST` `XMLMODIFY` `XMLNAMESPACES` `XMLPARSE` `XMLPI` `XMLQUERY` `XMLSERIALIZE` `XMLTEXT` `XMLXSROBJECTID` `YEAR`

Auf jede scalar-function folgen ein oder mehrere scalar-expressions in Klammern. Die Anzahl der scalar-expressions hängt von der scalar-function ab. Mehrere scalar-expressions müssen durch Kommata voneinander getrennt werden.

Beispiel:

    SELECT NAME
      INTO NAME
      FROM SQL-PERSONNEL
      WHERE SUBSTR ( NAME, 1, 3 ) = 'Fri'
           ...

#### column-function (aggregate-function)

Eine column-function gibt ein einwertiges Ergebnis für das Argument zurück, das sie erhält. Das Argument ist eine Menge gleichartiger Werte, z. B. die Werte einer Spalte. Column-functions werden auch aggregate-functions genannt.

Die folgenden column-functions entsprechen dem SQL-Standard. Sie sind nicht Db2-spezifisch:

`AVG`
`COUNT`
`MAX`
`MIN`
`SUM`

Die folgenden column-functions sind nicht konform mit dem SQL-Standard. Sie sind Db2-spezifisch und gehören zum Natural SQL Extended Set.

`COUNT_BIG`
`CORRELATION`
`COVARIANCE`
`COVAR_POP`
`COVARIANCE_SAMP`
`LISTAGG`
`MEDIAN`
`PERCENTILE_CONT`
`PERCENTILE_DISC`
`REGR_AVGX`
`REGR_AVGY`
`REGR_COUNT`
`REGR_ICPT`
`REGR_IMTERCEPT`
`REGR_R2`
`REGR_SLOPE`
`REGR_SXX`
`REGR_SXY`
`REGR_SYY`
`STDDEV`
`STDDEV_POP`
`STDDEV_SAMP`
`VAR`
`VAR_POP`
`VAR_SAMP`
`VARIANCE`
`VARIANCE_SAMP`
`XMLAGG`

#### scalar-operator

Der Verkettungsoperator (`CONCAT` oder `||`) beim scalar-operator entspricht nicht dem SQL-Standard. Er ist Db2-spezifisch und gehört zum Natural Extended Set.

#### special-register

Mit Ausnahme von `USER` entsprechen die folgenden special-registers nicht dem SQL-Standard. Sie sind Db2-spezifisch und gehören zum Natural SQL Extended Set:

`CURRENT APPLICATION COMPATIBILITY`
`CURRENT APPLICATION ENCODING SCHEME`
`CURRENT CLIENT_ACCNTG`
`CLIENT ACCNTG`
`CURRENT CLIENT_APPLNAME`
`CLIENT APPLNAME`
`CURRENT CLIENT_USERID`
`CLIENT USERID`
`CURRENT CLIENT_WRKSTNNAME`
`CLIENT WRKSTNNAME`
`CURRENT DATE`
`CURRENT_DATE`
`CURRENT DEBUG MODE`
`CURRENT DECFLOAT ROUNDING MODE`
`CURRENT DEGREE`
`CURRENT FUNCTION PATH`
`CURRENT GET_ACCEL_ARCHIVE`
`CURRENT_LC_CTYPE`
`CURRENT LC_CTYPE`
`CURRENT LOCALE LC_CTYPE`
`CURRENT LOCK TIMEOUT`
`CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION`
`CURRENT_MEMBER`
`CURRENT OPTIMIZATION HINT`
`CURRENT PACKAGE PATH`
`CURRENT PACKAGESET`
`CURRENT_PATH`
`CURRENT PRECISION`
`CURRENT QUERY ACCELERATION`
`CURRENT QUERY ACCELERATION WAITFORDATA`
`CURRENT REFRESH AGE`
`CURRENT ROUTINE VERSION`
`CURRENT RULES`
`CURRENT SCHEMA`
`CURRENT SERVER`
`CURRENT_SERVER`
`CURRENT SQLID`
`CURRENT TEMPORAL BUSINESS_TIME`
`CURRENT TEMPORAL_SYSTEM_TIME`
`CURRENT TIME`
`CURRENT_TIME`
`CURRENT TIMESTAMP`
`CURRENT TIMEZONE`
`CURRENT_TIMEZONE`
`CURRENT_TIMEZONE USER`
`SESSION TIME ZONE`
`SESSION_USER`
`USER`

Eine Referenz auf ein spezielles Register gibt einen skalaren Wert zurück.

Mit dem Kommando `SET CURRENT SQLID` kann der Ersteller-Name (`creator`) einer Tabelle durch die aktuelle SQLID ersetzt werden. Damit ist es möglich, auf identische Tabellen mit demselben Tabellennamen, aber mit unterschiedlichen Ersteller-Namen zuzugreifen.

#### units

Units (Einheiten), auch durations genannt, sind Db2-spezifisch und gehören zum Natural SQL Extended Set.

Die folgenden units werden unterstützt:

`DAY`
`DAYS`
`HOUR`
`HOURS`
`MICROSECOND`
`MICROSECONDS`
`MINUTE`
`MINUTES`
`MONTH`
`MONTHS`
`SECOND`
`SECONDS`
`YEAR`
`YEARS`

#### case-expression

`CASE` |  | searched-when-clause ... simple-when-clause |  |  | `ELSE` |  | `NULL` scalar expression |  |  | `END`

Case-expressions entsprechen nicht dem Standard-SQL und werden daher nur vom Natural SQL Extended Set unterstützt.

#### Beispiel:

    DEFINE DATA LOCAL
       01 #EMP
       02 #EMPNO (A10)
       02 #FIRSTNME (A15)
       02 #MIDINIT  (A5)
       02 #LASTNAME (A15)
       02 #EDLEVEL   (A13)
       02 #INCOME (P7)
       END-DEFINE
      SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME,
             (CASE WHEN EDLEVEL < 15 THEN 'SECONDARY'
                   WHEN EDLEVEL < 19 THEN 'COLLEGE'
                   ELSE             'POST GRADUATE'
              END ) AS EDUCATION, SALARY + COMM AS INCOME
             INTO
             #EMPNO, #FIRSTNME, #MIDINIT, #LASTNAME,
             #EDLEVEL, #INCOME
               FROM DSN8510-EMP
               WHERE (CASE WHEN SALARY = 0 THEN NULL
                                           ELSE SALARY / COMM
                                           END ) > 0.25
      DISPLAY #EMP
      END-SELECT
      END

### CALLDBPROC - SQL

Das Natural SQL-Statement `CALLDBPROC` wird für den Aufruf von Db2 Stored Procedures verwendet. Es unterstützt den Ergebnismengenmechanismus (`result-set`) von Db2 und ermöglicht den Aufruf von Db2 Stored Procedures. Weitere Einzelheiten und die Statement-Syntax finden Sie unter CALLDBPROC (SQL) in der Statements-Dokumentation.

Die folgenden Themen werden behandelt:

- Statische und dynamische Ausführung
- Result Sets (Ergebnismengen)
- Liste der Parameterdatentypen
- CALLMODE=NATURAL
- Beispiel für CALLDBPROC/READ RESULT SET

#### Statische und dynamische Ausführung

Wenn das `CALLDBPROC`-Statement dynamisch ausgeführt wird, werden alle Parameter und Konstanten auf die Variablen des folgenden Db2 SQL-Statement abgebildet:

    CALL :hv USING  DESCRIPTOR :sqlda statement

`:hv` bezeichnet eine Host-Variable, die den Namen der aufzurufenden Prozedur enthält.

`:sqlda` ist eine dynamisch generierte sqlda, die die Parameter beschreibt, die an die Stored Procedure übergeben werden sollen.

Wenn das `CALLDBPROC`-Statement statisch ausgeführt wird, werden die Konstanten des `CALLDBPROC`-Statements auch als Konstanten in dem generierten Assembler SQL-Quellcode für den Db2 Precompiler erzeugt.

#### Result Sets (Ergebnismengen)

Wenn der von dem `CALL`-Statement erzeugte SQLCODE anzeigt, dass es Ergebnismengen gibt (SQLCODE `+466` und `+464`), führt die Natural for Db2-Laufzeit ein `DESCRIBE PROCEDURE :hv INTO : sqlda`-Statement aus, um die `result set locator`-Werte der von der aufgerufenen Stored Procedure erzeugten Ergebnismengen abzurufen. Diese Werte werden in die `RESULT SETS`-Variablen gestellt, die in dem `CALLDBPROC`-Statement angegeben sind. Jede in einem `CALLDBPROC` angegebene `RESULT SETS`-Variable, für die kein `result set locator`-Wert vorhanden ist, wird auf Null zurückgesetzt. Die `result set locator`-Werte können zum Lesen der Ergebnismengen mit dem `READ RESULT SET`-Statement verwendet werden, solange die Datenbanktransaktion, die die Ergebnismenge erzeugt hat, noch kein `COMMIT` oder `ROLLBACK` abgesetzt hat.

Wurde die Ergebnismenge durch einen Cursor `WITH HOLD` erzeugt, bleibt der `result set locator`-Wert auch nach einer `COMMIT`-Operation gültig.

Im Gegensatz zu anderen Natural SQL-Statements können Sie bei `CALLDBPROC` (optional!) nach dem Schlüsselwort `GIVING` eine SQLCODE-Variable angeben, die den SQLCODE des zugrunde liegenden `CALL`-Statements enthält. Wenn `GIVING` angegeben wird, ist es Aufgabe des Natural-Programms, auf den SQLCODE zu reagieren (die Fehlermeldung NAT3700 wird von der Laufzeit nicht ausgegeben).

#### Liste der Parameterdatentypen

Im Folgenden werden die vom Statement `CALLDBPROC` unterstützten Parameterdatentypen aufgeführt:

Natural-Format/Länge | Db2-Datentyp
--- | ---
An | `CHAR(n)`
B2 | `SMALLINT`
B4 | `INT`
Bn (n = not equal 2 or 4) | `CHAR(n)`
F4 | `REAL`
F8 | `DOUBLE PRECISION`
I2 | `SMALLINT`
I4 | `INT`
Nnn.m | `NUMERIC(nn+m,m)`
Pnn.m | `NUMERIC(nn+m,n)`
Gn | `GRAPHIC(n)`
An/1:m | `VARCHAR(n*m)`
D | `DATE`
T | `TIME` Anmerkung Das Natural-Format T hat einen größeren Datenbereich als der entsprechende Db2 `TIME`-Datentyp. Im Vergleich zu Db2 `TIME` verfügt die Natural-Variable T außerdem über einen Datumsanteil (Jahr, Monat, Tag) und die Zehntelsekunde. Daher schneidet Natural for Db2 bei der Konvertierung einer Natural-Variablen T in einen Db2-`TIME`-Wert den Datumsanteil und die Zehntelsekunde ab. Bei der Konvertierung von Db2 `TIME` in das Natural-Format T wird der Datumsanteil auf `0000-01-02` und der Zehntelsekundenanteil in Natural auf `0` zurückgesetzt.

#### CALLMODE=NATURAL

Dieser Parameter wird verwendet, um Natural Stored Procedures aufzurufen, die mit `PARAMETER STYLE GENERAL/WITH NULL` definiert wurden.

Wenn der Parameter `CALLMODE=NATURAL` angegeben ist, wird ein zusätzlicher Parameter, der die an die Natural Stored Procedure übergebenen Parameter beschreibt, vom Client, d.h. dem Aufrufer, an den Server, d.h. den Natural for Db2 Server Stub, übergeben. Der Parameter ist der Stored Procedure Control Block (STCB; siehe auch STCB Layout in PARAMETER STYLE im Abschnitt Verarbeitung von Natural Stored Procedures und UDFs) und hat aus Sicht von Db2 das Format `VARCHAR`. Daher muss jede Natural Stored Procedure, die mit `PARAMETER STYLE GENERAL/WITH NULL` definiert ist, mit dem `CREATE PROCEDURE`-Statement definiert werden, indem dieser `VARCHAR`-Parameter als erster in seiner `PARMLIST`-Zeile verwendet wird.

Aus der Sicht des Aufrufers, d.h. des Natural-Programms, und aus der Sicht der Stored Procedure, d.h. des Natural-Subprogramms, ist der STCB unsichtbar. Er wird als erster Parameter von der Natural for Db2-Laufzeit übergeben und auf der Server-Seite verwendet, um die Kopie der übergebenen Daten im Natural-Thread und dem entsprechenden `CALLNAT`-Statement zu erstellen. Außerdem dient dieser Parameter als Container für Fehlerinformationen, die während der Ausführung der Natural-Stored-Procedure durch die Natural-Laufzeit erzeugt werden. Er enthält auch Informationen über die Library, in der Sie angemeldet sind, und das aufzurufende Natural-Subprogramm.

#### Beispiel für CALLDBPROC/READ RESULT SET

Nachfolgend finden Sie ein Beispielprogramm für die Ausführung der Statements `CALLDBPROC` und `READ RESULT SET`:

    DEFINE DATA LOCAL
      1 ALPHA       (A8)
      1 NUMERIC     (N7.3)
      1 PACKED      (P9.4)
      1 VCHAR       (A20/1:5) INIT     <'DB25SGCP'>
      1 INTEGER2    (I2)
      1 INTEGER4    (I4)
      1 BINARY2     (B2)
      1 BINARY4     (B4)
      1 BINARY12    (B12)
      1 FLOAT4      (F4)
      1 FLOAT8      (F8)
      1 INDEX-ARRAY (I2/1:11)
      1 INDEX-ARRAY1(I2)
      1 INDEX-ARRAY2(I2)
      1 INDEX-ARRAY3(I2)
      1 INDEX-ARRAY4(I2)
      1 INDEX-ARRAY5(I2)
      1 INDEX-ARRAY6(I2)
      1 INDEX-ARRAY7(I2)
      1 INDEX-ARRAY8(I2)
      1 INDEX-ARRAY9(I2)
      1 INDEX-ARRAY10(I2)
      1 INDEX-ARRAY11(I2)
      1 #RESP        (I4)
      1 #RS1         (I4) INIT <99>
      1 #RS2         (I4) INIT <99>
      LOCAL
      1 V1 VIEW OF SYSIBM-SYSTABLES
      2 NAME
      1 V2 VIEW OF SYSIBM-SYSPROCEDURES
      2 PROCEDURE
      2 RESULT_SETS
      1 V (I2) INIT <99>
      END-DEFINE
      CALLDBPROC 'DAEFDB25.SYSPROC.SNGSTPC'  DSN8510-EMP
       ALPHA  INDICATOR :INDEX-ARRAY1
       NUMERIC INDICATOR :INDEX-ARRAY2
       PACKED  INDICATOR :INDEX-ARRAY3
       VCHAR(*) INDICATOR :INDEX-ARRAY4
       INTEGER2 INDICATOR :INDEX-ARRAY5
       INTEGER4 INDICATOR :INDEX-ARRAY6
       BINARY2  INDICATOR :INDEX-ARRAY7
       BINARY4  INDICATOR :INDEX-ARRAY8
       BINARY12 INDICATOR :INDEX-ARRAY9
       FLOAT4   INDICATOR :INDEX-ARRAY10
       FLOAT8   INDICATOR :INDEX-ARRAY11
        RESULT SETS #RS1 #RS2
       CALLMODE=NATURAL
      READ (10) RESULT SET #RS2 INTO VIEW V2 FROM SYSIBM-SYSTABLES
      WRITE 'PROC F RS  :' PROCEDURE 50T RESULT_SETS
      END-RESULT
      END

### COMMIT - SQL

Das Natural SQL-Statement `COMMIT` zeigt das Ende einer logischen Transaktion an und gibt alle während der Transaktion gesperrten Db2-Daten frei. Alle Datenänderungen werden permanent gemacht. Weitere Einzelheiten und die Statement-Syntax finden Sie unter COMMIT (SQL) in der Statements-Dokumentation.

`COMMIT` ist ein Synonym für das native Natural DML-Statement `END TRANSACTION`, das im Abschnitt Verwendung von nativen Natural DML-Statements beschrieben ist.

Mit dem `COMMIT`-Statement können keine Transaktionsdaten mitgegeben werden.

Wenn dieses Statement von einer Natural Stored Procedure oder einer benutzerdefinierten Funktion (UDF) ausgeführt wird, führt Natural for Db2 die zugrunde liegende Commit-Operation nicht aus. Dadurch kann die Natural Stored Procedure bzw. die benutzerdefinierte Funktion (UDF) ein Commit auf Updates bei Nicht-Db2-Datenbanken ausführen.

Unter CICS wird das `COMMIT`-Statement in ein `EXEC CICS SYNCPOINT`-Kommando übersetzt. Wird der File Server verwendet, wird nach jeder Terminal-E/A ein implizites Transaktionsende ausgegeben. Dies liegt an der CICS-spezifischen Transaktionsverarbeitung im Pseudo-Conversational Mode, siehe Natural for Db2 unter CICS.

Unter IMS TM wird das `COMMIT`-Statement nicht in ein IMS `CHECKPOINT`-Kommando übersetzt, sondern ignoriert. Ein implizites Transaktionsende wird nach jeder Terminal-E/A ausgegeben. Dies liegt an der IMS TM-spezifischen Transaktionsverarbeitung, siehe Natural for Db2 unter IMS TM.

Ein `COMMIT`-Statement darf nicht innerhalb einer Datenbankschleife stehen, es sei denn, es wird in Kombination mit der `WITH HOLD`-Klausel verwendet (siehe Syntax 1 - Cursor-orientierte Selektion in SELECT (SQL) in der Statements-Dokumentation), da alle Cursor am Ende einer logischen Arbeitseinheit geschlossen werden. Stattdessen muss sie außerhalb einer solchen Schleife bzw. bei geschachtelten Schleifen nach der äußersten Schleife stehen.

Wenn ein externes Programm, das in einer anderen Standardprogrammiersprache geschrieben wurde, von einem Natural-Programm aufgerufen wird, darf dieses externe Programm kein eigenes `COMMIT`-Kommando enthalten, wenn das Natural-Programm ebenfalls Datenbankaufrufe tätigt. Das aufrufende Natural-Programm muss das `COMMIT`-Statement für das externe Programm absetzen.

### DELETE - SQL

Im Rahmen von Natural SQL werden sowohl das cursororientierte bzw. Positioned `DELETE` als auch das nicht-cursororientierte bzw. Searched `DELETE` unterstützt. Die Funktionalität des Positioned `DELETE` entspricht derjenigen des Natural DML `DELETE`. Weitere Einzelheiten und die Statement-Syntax finden Sie unter DELETE (SQL) in der Natural-Statements-Dokumentation.

Bei Db2 kann ein Tabellenname in der FROM-Klausel eines Searched `DELETE`-Statements mit einem `correlation-name` versehen werden. Dies entspricht nicht der Standard-SQL-Syntaxdefinition und gehört daher zum Natural SQL Extended Set.

Das Searched `DELETE`-Statement muss z.B. verwendet werden, um eine Zeile aus einer selbstreferenzierenden Tabelle zu löschen, da bei selbstreferenzierenden Tabellen ein Positioned `DELETE` von Db2 nicht zugelassen wird.

### INSERT - SQL

Das Natural SQL `INSERT`-Statement wird verwendet, um eine oder mehrere neue Zeilen zu einer Tabelle hinzuzufügen.

Da das `INSERT`-Statement einen `select-expression` enthalten kann, gelten alle oben beschriebenen Db2-spezifischen gemeinsamen Syntaxelemente.

Weitere Einzelheiten und die Statement-Syntax finden Sie unter INSERT (SQL) in der Natural-Statements-Dokumentation.

### MERGE - SQL

Das `MERGE`-Statement ist ein hybrides SQL-Statement, das aus einer `UPDATE`- und einer I`NSERT`-Komponente besteht. Es ermöglicht Ihnen, entweder eine Zeile in eine Db2-Tabelle einzufügen oder eine Zeile einer Db2-Tabelle zu aktualisieren, wenn die Eingabedaten mit einer bereits existierenden Zeile einer Tabelle übereinstimmen.

Das `MERGE`-Statement gehört zum SQL Extended Set.

Weitere Einzelheiten und die Statement-Syntax finden Sie unter MERGE (SQL) in der Natural-Statements-Dokumentation.

### PROCESS SQL

Das Natural `PROCESS SQL`-Statement wird verwendet, um SQL-Statements an die zugrunde liegende Datenbank zu senden. Die Statements werden in einem `statement-string` angegeben, der auch Konstanten und Parameter enthalten kann. Der Set von Statements, die ausgegeben werden können, wird auch als Flexible SQL bezeichnet und umfasst diejenigen Statements, die mit dem SQL-Statement `EXECUTE` ausgegeben werden können.

Darüber hinaus umfasst Flexible SQL die folgenden Db2-spezifischen Statements:

`CALL`
`CONNECT`
`GET DIAGNOSTICS`
`SET APPLICATION ENCODING SCHEME`
`SET CONNECTION`
`SET CURRENT DEGREE`
`SET CURRENT LC_CTYPE`
`SET CURRENT OPTIMIZATION HINT`
`SET CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION`
`SET CURRENT PACKAGE PATH`
`SET CURRENT PACKAGESET`
`SET CURRENT PATH`
`SET CURRENT PRECISION`
`SET CURRENT REFRESH AGE`
`SET CURRENT RULES`
`SET CURRENT SCHEMA`
`SET CURRENT SQLID`
`SET ENCRYPTION PASSWORD`
`SET host-variable=special-register`
`RELEASE`

Anmerkungen:

1. SQL-Statements, die über `PROCESS SQL` ausgegeben werden, werden bei der statischen Generierung übersprungen. Sie werden daher immer dynamisch über `NDBIOMO` ausgeführt.
2. Um Probleme bei der Transaktionssynchronisation zwischen der Natural-Umgebung und Db2 zu vermeiden, dürfen die Statements `COMMIT` und `ROLLBACK` im `PROCESS SQL` nicht verwendet werden.

Weitere Einzelheiten und die Statement-Syntax finden Sie unter PROCESS SQL in der Statements-Dokumentation.

### READ RESULT SET - SQL

Das Natural SQL-Statement `READ RESULT SET` liest eine Ergebnismenge (`result-set`), die von einer Natural Stored Procedure erzeugt wurde, die durch ein `CALLDBPROC`-Statement aufgerufen wurde. Wie Sie die Scroll-Richtung mit Hilfe der Variablen scroll-hv angeben, erfahren Sie beim `SELECT`-Statement.

Weitere Einzelheiten und die Statement-Syntax siehe READ RESULT SET (SQL) in der Statements-Dokumentation.

### ROLLBACK - SQL

Das Natural SQL-Statement `ROLLBACK` macht alle Datenbankänderungen rückgängig, die seit Beginn der letzten logischen Transaktion vorgenommen wurden. Logische Transaktionen können entweder nach dem Beginn einer Sitzung oder nach dem letzten `COMMIT`/`END TRANSACTION`-Statement oder der `ROLLBACK`/`BACKOUT TRANSACTION`-Statement beginnen. Alle Datensätze, die während der Transaktion gehalten wurden, werden freigegeben.

Das Natural SQL-Statement `ROLLBACK` macht alle Datenbankänderungen rückgängig, die seit Beginn der letzten logischen Transaktion vorgenommen wurden. Logische Transaktionen können entweder nach dem Beginn einer Sitzung oder nach dem letzten COMMIT-/END TRANSACTION- oder der ROLLBACK-/BACKOUT TRANSACTION-Statement beginnen. Alle Datensätze, die während der Transaktion gehalten wurden, werden freigegeben.

Weitere Einzelheiten und die Statement-Syntax finden Sie unter `ROLLBACK (SQL)` in der Statements-Dokumentation.

`ROLLBACK` ist ein Synonym für das Natural-Statement `BACKOUT TRANSACTION`, das im Abschnitt Verwendung von nativen Natural DML-Statements beschrieben ist.

Wenn dieses Kommando von einer Natural Stored Procedure oder einer benutzerdefinierten Funktion (UDF) aus ausgeführt wird, führt Natural for Db2 die zugrunde liegende Rollback-Operation aus. Dadurch wird der Aufrufer (Caller) in einen Must-Rollback-Zustand versetzt. Wenn dieses Kommando von einer Natural-Fehlerverarbeitung (implizites `ROLLBACK`) ausgeführt wird, führt Natural for Db2 die zugrunde liegende Rollback-Operation nicht aus, so dass der Aufrufer den ursprünglichen Natural-Fehler erhalten kann.

Unter CICS wird das Statement `ROLLBACK` in einen `EXEC CICS ROLLBACK`-Kommando übersetzt. Bei Verwendung des File Servers werden jedoch nur die seit der letzten Terminal-E/A an der Datenbank vorgenommenen Änderungen rückgängig gemacht. Dies liegt an der CICS-spezifischen Transaktionsverarbeitung im Pseudo-Conversational Mode, siehe Natural for Db2 unter CICS.

Unter IMS TM wird das `ROLLBACK`-Statement in ein IMS-Rollback-Kommando (`ROLB`) übersetzt. Es werden jedoch nur die Änderungen an der Datenbank rückgängig gemacht, die seit der letzten Terminal-E/A vorgenommen wurden. Dies liegt an der IMS TM-spezifischen Transaktionsverarbeitung, siehe Natural for Db2 unter IMS TM.

Da alle Cursor am Ende einer logischen Arbeitseinheit geschlossen werden, darf ein `ROLLBACK`-Statement nicht innerhalb einer Datenbankschleife stehen, sondern muss außerhalb einer solchen Schleife oder bei geschachtelten Schleifen nach der äußersten Schleife stehen.

Wenn ein externes Programm, das in einer anderen Standardprogrammiersprache geschrieben wurde, von einem Natural-Programm aufgerufen wird, darf dieses externe Programm kein eigenes `ROLLBACK-`Kommando enthalten, wenn das Natural-Programm auch Datenbankaufrufe absetzt. Das aufrufende Natural-Programm muss das `ROLLBACK`-Statement für das externe Programm absetzen.

### SELECT - SQL

Das Natural SQL `SELECT`-Statement unterstützt sowohl die cursororientierte Auswahl, mit der eine beliebige Anzahl an Zeilen abgerufen werden kann, als auch die nicht-cursororientierte Auswahl (Singleton `SELECT`), mit der höchstens eine einzige Zeile abgerufen werden kann.

Alle Einzelheiten und die Statement-Syntax finden Sie unter SELECT (SQL) in der Statements-Dokumentation.

#### SELECT - Cursor-orientiert

Wie das native DML-Statement `FIND` wird das cursororientierte `SELECT`-Statement verwendet, um eine Reihe von Zeilen (Datensätzen) aus einer oder mehreren Db2-Tabellen anhand eines Suchkriteriums auszuwählen. Da eine Datenbankschleife initiiert wird, muss die Schleife durch ein `LOOP`-Statement (im Reporting Mode) oder durch ein `END-SELECT`-Statement (im Structured Mode) geschlossen werden. Bei dieser Vorgehensweise verwendet Natural die gleiche Schleifenverarbeitung wie bei einem `FIND`-Statement. Außerdem ist keine Cursor-Verwaltung durch das Anwendungsprogramm erforderlich. Sie wird automatisch von Natural durchgeführt.

Weitere Einzelheiten und die Syntax finden Sie unter Syntax 1 − Cursor-orientierte Auswahl in SELECT (SQL) in der Statements-Dokumentation.

#### SELECT SINGLE - Nicht cursor-orientiert

Das Natural SQL-Statement `SELECT SINGLE` bietet die Funktionalität einer Nicht-Cursor-Auswahl (Singleton `SELECT`), d. h. eines `select-expression`, der maximal eine Zeile ohne Verwendung eines Cursors abruft.

Da Db2 das Singleton `SELECT`-Kommando nur in statischem SQL unterstützt, wird das Natural-`SELECT SINGLE`-Statement im dynamischen Modus wie ein Set-Level-`SELECT`-Statement ausgeführt, was zu einer Cursor-Operation führt. Natural prüft jedoch die Anzahl der von Db2 zurückgegebenen Zeilen. Wenn mehr als eine Zeile ausgewählt wird, wird eine entsprechende Fehlermeldung zurückgegeben.

Weitere Einzelheiten und die Syntax finden Sie unter Syntax 2 - Nicht cursor-orientierte Auswahl in SELECT (SQL) in der Statements-Dokumentation.

### UPDATE - SQL

Sowohl das cursororientierte oder Positioned `UPDATE` als auch die nicht-cursororientierte oder Searched `UPDATE`-Statement wird als Teil von Natural SQL unterstützt. Beide referenzieren entweder eine Tabelle oder eine Natural-View.

Bei Db2 kann der Name einer Tabelle oder einer Natural-View, die durch ein Searched `UPDATE` referenziert werden soll, mit einem `correlation-name` versehen werden. Dieser entspricht nicht der Standard-SQL-Syntaxdefinition und gehört daher zum Natural Extended Set.

Das Searched `UPDATE` Statement muss z.B. zur Aktualisierung eines Primärschlüsselfeldes verwendet werden, da Db2 die Aktualisierung von Spalten eines Primärschlüssels mit einem Positioned `UPDATE`-Statement nicht erlaubt.

Anmerkung
Wenn Sie die Notation `SET *` verwenden, werden alle Felder der referenzierten Natural-View zu den Listen `FOR UPDATE OF` und `SET` hinzugefügt. Stellen Sie daher sicher, dass Ihre View nur Felder enthält, die aktualisiert werden können. Andernfalls wird von Db2 ein negativer SQLCODE zurückgegeben.

Weitere Einzelheiten und die Syntax finden Sie unter UPDATE (SQL) in der Statements-Dokumentation.

## Verwendung von Natural-Systemvariablen

Bei der Verwendung mit Db2 gibt es Einschränkungen und/oder zu beachtende Punkte in Bezug auf die folgenden Natural-Systemvariablen:

- `*ISN`

- `*NUMBER`

- `*ROWCOUNT`

Informationen über Einschränkungen und/oder zu beachtende Punkte finden Sie im Abschnitt Datenbank-spezifische Anmerkungen in der entsprechenden Systemvariablen-Dokumentation.

## Verarbeitung mehrerer Zeilen

Dieser Abschnitt beschreibt die Multiple Row Processing-Funktionalität für Db2 Datenbanken.

Sie müssen mit Db2 for z/OS Version 8 oder höher arbeiten, um diese Funktionalität nutzen zu können.

Natural for Db2 bietet zwei Arten von Funktionen zur Verarbeitung mehrerer Zeilen:

- #### Standard-Mehrzeilenverarbeitung

- Diese Funktion hat keinen Einfluss auf die Programmlogik. Obwohl Natural Native DML und Natural SQL DML Klauseln zur Angabe des Multi-Fetch-Faktors bereitstellen, arbeitet das Natural-Programm mit einer Datenbankzeile und aus Sicht des Programms wird nur eine Zeile von der Datenbank empfangen oder an die Datenbank gesendet.

- #### Erweiterte Mehrzeilenverarbeitung

  Diese Funktion ist nur mit Natural SQL DML verfügbar und hat erhebliche Auswirkungen auf die Programmlogik, da sie das Abrufen mehrerer Zeilen aus der Datenbank in den Programmspeicher durch ein einziges Natural SQL `SELECT`-Statement in ein Set von Arrays ermöglicht. Außerdem ist es möglich, mehrere Zeilen aus einem Set von Arrays mit dem Natural SQL `INSERT`-Statement in die Datenbank einzufügen.

Im Folgenden finden Sie Informationen zu den folgenden Themen:

- Zweck der Multi-Fetch-Funktion (Standard)

- Bei Multi-Fetch-Nutzung (Standard) zu berücksichtigende Punkte

- Größe des Multi-Fetch-Puffers (Standard)

- Unterstützung von TEST DBLOG Q (Standard)

- Mehrere Zeilen an Programm (erweitert)

- Mehrere Zeilen aus Programm (Erweitert)

### Zweck der Multi-Fetch-Funktion (Standard)

Im Standardmodus liest Natural nicht mehrere Datensätze mit einem einzigen Datenbankaufruf, sondern arbeitet immer im Modus "Ein Datensatz pro Abruf". Diese Art des Betriebs ist zuverlässig und stabil, kann aber einige Zeit in Anspruch nehmen, wenn eine große Anzahl von Datenbanksätzen verarbeitet wird.

Um die Leistung dieser Programme zu verbessern, können Sie die Multi-Fetch-Klausel in den Natural DML-Statements `FIND`, `READ` oder `HISTOGRAM` verwenden. Damit können Sie die Anzahl der pro Datenbankzugriff gelesenen Datensätze angeben.

| `FIND` |  |  | `MULTI-FETCH` |  | `ON` |  |
`READ` | `OFF`
`HISTOGRAM` | `OF` multi-fetch-factor

wobei `multi-fetch-factor` entweder eine Konstante oder eine Variable mit dem Format Integer (I4) ist.

Um die Performance des Natural SQL `SELECT`-Statements zu erhöhen, können Sie die `WITH ROWSET POSITIONING FOR`-Klausel verwenden, um einen Multi-Fetch-Faktor anzugeben.

| `WITH ROWSET POSITIONING FOR` |  | [:] row_hv |  | `ROWS` |
integer

Zur Ausführungszeit des Statements prüft die Laufzeit, ob ein Multi-Fetch-Faktor größer als 1 für das Datenbank-Statement angegeben ist.

Ist der `multi-fetch-factor`

kleiner oder gleich 1, | wird der Datenbankaufruf im üblichen Modus "Ein Datensatz pro Zugriff" fortgesetzt.
größer als 1, | wird der Datenbankaufruf dynamisch vorbereitet, um mehrere Sätze (z.B. 10) mit einem einzigen Datenbankzugriff in einen Hilfspuffer (Multi-Fetch-Puffer) zu lesen. Bei Erfolg wird der erste Datensatz in die zugrunde liegende Datensicht übertragen. Bei der Ausführung der nächsten Schleife wird die Datensicht direkt aus dem Multi-Fetch-Puffer gefüllt, ohne Datenbankzugriff. Nachdem alle Datensätze aus dem Multi-Fetch-Puffer geholt wurden, bewirkt die nächste Schleife, dass der nächste Datensatz aus der Datenbank gelesen wird. Wird die Datenbankschleife beendet (entweder durch End-of-Records, `ESCAPE`, `STOP` usw.), wird der Inhalt des Multi-Fetch-Puffers freigegeben.

### Bei Multi-Fetch-Nutzung (Standard) zu berücksichtigende Punkte

- Das Programm erhält nicht bei jeder Schleife "frische" Datensätze aus der Datenbank, sondern arbeitet mit Abbildern, die beim letzten Multi-Fetch-Zugriff abgerufen wurden.

- Wenn für ein Natural DML `READ`- oder `HISTOGRAM`-Statement ein dynamischer Richtungswechsel (`IN DYNAMIC...SEQUENCE`) kodiert wird, ist die Multi-Fetch-Funktion nicht möglich und führt zu einem entsprechenden Syntaxfehler beim Kompilieren.

- Die Größe, die eine Datenbankschleife im Multi-Fetch-Puffer belegt, wird nach der folgenden Regel ermittelt:

  header + sqldaheader + columns*(sqlvar+lise) + mf*(udind + sum(collen) + sum(LF(columns) + sum(nullind))
  =
  32 + 16 + columns*(44+12) + mf*(1 + sum(collen) + sum(LF(column)) + sum(2))

Dabei ist:

header | Länge des Header eines Eintrags im Db2-Multifetch-Puffer, d.h. 32
sqldaheader | Länge des Header einer sqlda, d.h. 16
columns | Anzahl der aufnehmenden Felder einer SQL-Anfrage
sqlvar | Länge eines sqlvar, d. h. 44
lise | Länge einer Natrual für Db2 spezifischen sqlvar-Erweiterung
mf | Multifetch-Faktor, d.h. die Anzahl der Zeilen, die durch einen Datenbankaufruf geholt werden
collen | Länge des aufnehmenden Feldes
LF(column) | Größe des Längenfeldes des aufnehmenden Feldes, d. h. 0 für Felder mit fester Länge, 2 für Felder mit variabler Länge und 4 für große Objektspalten (LOBs)
nullind | Länge eines Null-Indikators, d. h. 2

### Größe des Multi-Fetch-Puffers (Standard)

Der Multi-Fetch-Puffer wird bei der Terminal-Eingabe im Pseudo-Conversional Mode freigegeben. Daher gibt es keine Größenbeschränkung für den Db2-Multi-Fetch-Puffer (`DB2SIZE6`). Der Puffer wird bei Bedarf automatisch vergrößert.

### Unterstützung von TEST DBLOG Q (Standard)

Wenn Multi-Fetch verwendet wird, werden "reale" Datenbankaufrufe nur übermittelt, um einen neuen Satz an Datensätzen zu erhalten.

Die Funktion `TEST DBLOG Q` wird auch vom Natural for Db2 Multi-Fetch-Handler für jeden Rowset-Fetch aus Db2 und für jeden aus dem Multi-Fetch-Puffer in den Programmspeicher verschobenen Datensatz aufgerufen. Die Ereignisse werden durch das Literal `MULTI FETCH ...` und `<BUFF FETCH ...` unterschieden.

#### Beispiel: TEST DBLOG List Break-Out

    10:51:57              ***** NATURAL Test Utilities *****             2006-01-27
    User HGK                        - DBLOG Trace -                Library NDB42
    M No   R SQL Statement (truncated)     CU SN SREF M Typ SQLC/W Program  Line LV
    _    1   SELECT EMPNO,FIRSTNME,LASTNAM 01 01 0260 D DB2        MF000001 0260 01
    _    2     MULTI FETCH  NEX            01 01 0260 D DB2        MF000001 0260 01
    _    3     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _    4     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _    5     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _    6     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _    7     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _    8     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _    9     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _   10     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _   11     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _   12     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _   13     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _   14     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _   15     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _   16     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    _   17     <BUFF FETCH  NEX            00 00 0260 D DB2        MF000001 0260 01
    Command ===>

wobei die Spalte No für Folgendes steht:

1 | ist ein offener Cursor-Db2-Aufruf.
2 | ist ein "realer" Datenbankaufruf, der eine Reihe von Datensätzen über Multi-Fetch liest (siehe `MULTI FETCH NEX` in der Spalte SQL Statement).
3-17 | sind keine "realen" Datenbankaufrufe, sondern nur Einträge, die dokumentieren, dass das Programm diese Sätze aus dem Multi-Fetch-Puffer erhalten hat (siehe `<BUFF FETCH NEX` in der Spalte SQL-Statement).

### Mehrere Zeilen an Programm (erweitert)

Diese Funktion ermöglicht es Programmen, mehrere Zeilen aus Db2 in Arrays abzurufen.

Diese Funktion ist nur beim `SELECT`-Statement verfügbar.

- Voraussetzungen
- DB2ARRY=ON
- INTO Clause
- WITH ROWSET POSITIONING-Klausel
- ROWS_RETURNED-Klausel
- Einschränkungen und Vorbehalte
- File Server-Verwendung und Positioned UPDATE und DELETE

#### Voraussetzungen

Um diese Funktion zu nutzen:

1. Setzen Sie die Compiler-Option `DB2ARRY=ON` (unter Verwendung eines `OPTIONS`-Statements oder des `COMPOPT`-Kommandos oder des Profilparameters `CMPO`).

2. Geben Sie eine Liste von empfangenden Arrays in der `INTO`-Klausel (siehe into-clause) des `SELECT`-Statements an.

3. Geben Sie die Anzahl der Zeilen an, die mit einer einzigen `FETCH`-Operation mit der `WITH ROWSET POSITIONING`-Klausel aus der Datenbank abgerufen werden sollen.

4. Geben Sie eine Variable an, die die Anzahl der aus der Datenbank abgerufenen Zeilen über die `ROWS_RETURNED`-Klausel erhält.

#### DB2ARRY=ON

`DB2ARRY=ON` ist notwendig, um die Angabe von Arrays in der `INTO`-Klausel zu ermöglichen (siehe into-clause).

`DB2ARRY=ON` verhindert auch die Verwendung von Arrays als abgebende oder aufnehmende Felder bei Db2 `CHAR`/`VARCHAR` /`GRAPHIC`/`VARGRAPHIC`-Spalten. Stattdessen müssen Natural-Skalarfelder mit der entsprechenden Länge verwendet werden.

#### INTO Clause

Jedes in der `INTO`-Klausel (siehe into-clause) angegebene Array muss zusammenhängend sein (eine Ausprägung folgt unmittelbar auf eine andere, dies wird von Db2 erwartet) und muss eindimensional sein. Die Arrays werden von der ersten Ausprägung (low) bis zur letzten Ausprägung (high) aufgefüllt. Die ersten Array-Ausprägungen bilden die erste Zeile des erhaltenen Rowset, die zweiten Array-Ausprägungen bilden die zweite Zeile des erhaltenen Rowset. Die Array-Ausprägungen des n-ten Index bilden die n-te Zeile, die von Db2 zurückgegeben wird.

Wenn eine LINDICATOR-Klausel oder INDICATOR-Klausel in der `INTO`-Klausel für Arrays verwendet wird, müssen die angegebenen Längenindikatoren oder Nullindikatoren ebenfalls Arrays sein. Die Anzahl der Ausprägungen von `LINDICATOR`- und `INDICATOR`-Arrays muss gleich oder größer sein als die Anzahl der Ausprägungen des Master-Arrays.

#### WITH ROWSET POSITIONING-Klausel

Die `WITH_ROWSET_POSITIONING`-Klausel wird verwendet, um die Anzahl der Zeilen anzugeben, die in einem Verarbeitungszyklus aus der Datenbank abgerufen werden sollen. Die angegebene Anzahl muss gleich oder kleiner sein als das Minimum der Ausprägungen aller angegebenen Arrays. Wird eine Variable, nicht eine Konstante, angegeben, so wird der aktuelle Inhalt der Variablen bei jedem Verarbeitungszyklus verwendet. Die angegebene Zahl muss größer als `0` und kleiner als `32768` sein.

#### ROWS_RETURNED-Klausel

Die `ROWS_RETURNED`-Klausel wird verwendet, um eine Variable anzugeben, die die Anzahl der Zeilen enthält, die während der eigentlichen Fetch-Operation aus der Datenbank gelesen wurden. Das Format der Variablen muss I4 sein.

#### Einschränkungen und Vorbehalte

Natural-Views: Es ist nicht möglich, Natural-Arrays von Views in der `INTO`-Klausel zu verwenden (siehe into-clause), d.h. die Verwendung des Schlüsselworts `VIEW` ist nicht möglich.

#### File Server-Verwendung und Positioned UPDATE und DELETE

Der Zweck dieses Merkmals besteht darin, die Anzahl der Datenbank- und Datenbankschnittstellenaufrufe für die Massenstapelverarbeitung zu reduzieren. Daher ist es nicht empfehlenswert, diese Art der Programmierung in Online-CICS- oder IMS-Umgebungen zu verwenden, wenn Terminal-Ein- und -Ausgaben innerhalb offener Cursorschleifen erfolgen, d.h. der File Server verwendet wird. Erst recht ist es nicht möglich, nach einer Terminal-E/A ein Positioned `UPDATE`- oder Positioned `DELETE`-Statement durchzuführen.

Beispiel:

    DEFINE DATA LOCAL
    01 NAME            (A20/1:10)
    01 ADDRESS         (A100/1:10)
    01 DATEOFBIRTH     (A10/1:10)
    01 SALARY          (P4.2/1:10)
    01 L$ADDRESS       (I2/1:10)
    01 ROWS            (I4)
    01 NUMBER          (I4)
    01 INDEX           (I4)
    END-DEFINE
    OPTIONS DB2ARRY=ON
    ASSIGN NUMBER := 10
    SEL.
    SELECT NAME, ADDRESS , DATEOFBIRTH, SALARY
           INTO  :NAME(*),                             /* <-- ARRAY
                 :ADDRESS(*) LINDICATOR :L$ADDRESS(*), /* <-- ARRAY
                 :DATEOFBIRTH(1:10),                   /* <-- ARRAY
                 :SALARY(01:10)                        /* <-- ARRAY
          FROM NAT-DEMO
          WHERE NAME > ' '
          WITH ROWSET POSITIONING FOR :NUMBER ROWS     /* <-- ROWS REQ
          ROWS_RETURNED :ROWS                          /* <-- ROWS RET
      IF ROWS > 0
        FOR INDEX = 1 TO  ROWS STEP 1
          DISPLAY
                  INDEX (EM=99) *COUNTER (SEL.) (EM=99) ROWS (EM=99)
                  NAME(INDEX)
                  ADDRESS(INDEX) (AL=20)
                  DATEOFBIRTH(INDEX)
                  SALARY(INDEX)
        END-FOR
      END-IF
    END-SELECT
    END

### Mehrere Zeilen aus Programm (Erweitert)

Diese Funktion ermöglicht es Programmen, mehrere Zeilen aus Arrays in eine Db2-Tabelle einzufügen.

Diese Funktion ist nur mit dem Natural-SQL-`INSERT`-Statement verfügbar.

#### Voraussetzungen

Um dieses Merkmal zu nutzen:

1. Setzen Sie die Compiler-Option `DB2ARRY=ON` (mit einem `OPTIONS`-Statement oder dem `COMPOPT`-Kommando oder dem Profilparameter `CMPO`).

2. Geben Sie eine Liste von sendenden Arrays in der VALUES-Klausel des Natural-SQL-`INSERT`-Statement an.

3. Geben Sie mit der FOR n ROWS-Klausel die Anzahl der Zeilen an, die mit einem einzelnen Natural-SQL-`INSERT`-Statement in die Datenbank eingefügt werden sollen.

#### DB2ARRY=ON

`DB2ARRY=ON` ist notwendig, um die Angabe von Arrays in der VALUES-Klausel zu ermöglichen. `DB2ARRY=ON` verhindert auch die Verwendung von Arrays als abgebende oder aufnehmende Felder für Db2 `CHAR`/`VARCHAR` /`GRAPHIC`/`VARGRAPHIC`-Spalten. Stattdessen müssen Natural-Skalarfelder mit der entsprechenden Länge verwendet werden.

#### VALUES-Klausel

Jedes in der VALUES-Klausel angegebene Array muss zusammenhängend sein (eine Ausprägung folgt unmittelbar auf eine andere, dies wird von Db2 erwartet) und muss eindimensional sein. Die Arrays werden von der ersten Ausprägung (niedrig) bis zur letzten Ausprägung (hoch) gelesen. Die ersten Ausprägungen des Arrays bilden die erste in die Datenbank eingefügte Zeile, die zweiten Ausprägungen des Arrays bilden die zweite in die Datenbank eingefügte Zeile. Die Array-Ausprägungen des n-ten Index bilden die n-te in die Datenbank eingefügte Zeile.

Wenn eine LINDICATOR-Klausel oder INDICATOR-Klausel in der VALUES-Klausel für Arrays verwendet wird, müssen die angegebenen Längenindikatoren oder Nullindikatoren ebenfalls Arrays sein. Die Anzahl der `LINDICATOR`- und `INDICATOR`-Array-Ausprägungen muss gleich oder größer sein als die Anzahl der Ausprägungen des Master-Array.

#### FOR n ROWS-Klausel

Die FOR n ROWS-Klausel wird verwendet, um anzugeben, wie viele Zeilen durch eine `INSERT`-Anweisung in die Datenbanktabelle eingefügt werden sollen. Die angegebene Anzahl muss gleich der oder kleiner sein als die Mindestanzahl der Ausprägungen aller angegebenen Arrays in der VALUES-Klausel. Die angegebene Zahl muss größer als `0` und kleiner als `32768` sein.

#### Einschränkungen und Vorbehalte

- #### Natural-Views

  Es ist nicht möglich, Natural-Arrays von Views in der VALUES-Klausel zu verwenden, d.h. die Verwendung des Schlüsselworts `VIEW` ist nicht möglich.

- #### Statische Ausführung

  Aufgrund von Db2-Einschränkungen ist es nicht möglich, Einfügungen mehrerer Zeilen im statischen Modus auszuführen. Daher werden mehrzeilige Einfügungen nicht statisch generiert, sondern immer dynamisch von Natural for Db2 vorbereitet und ausgeführt.

  Die statische Generierung mit Natural for Db2 erzeugt ein SQL-Programm in Assemblersprache, das vom Db2-Precompiler vorkompiliert wird, der wiederum ein DBRM erzeugt, das für die statische Ausführung erforderlich ist. Der Db2-Assembler-Precompiler bietet jedoch keine Unterstützung für Host-Variablen-Arrays. Sie können nur verwendet werden, wenn sie in einer SQLDA-Struktur angegeben sind, die zur Ausführungszeit erstellt werden muss. Ein statisches `INSERT` mit einer `VALUES`-Klausel für mehrere Zeilen erlaubt jedoch nicht die Angabe einer SQLDA, sondern nur Host-Variablen-Arrays, die vom Db2-Assembler-Precompiler nicht unterstützt werden.

  Es ist nicht möglich, Natural-Arrays von Views in der `INTO-`Klausel zu verwenden (siehe into-clause), d.h. die Verwendung des Schlüsselworts `VIEW` ist nicht möglich.

  Beispiel:

      DEFINE DATA LOCAL
      01 NAME        (A20/1:10)  INIT <'ZILLER1','ZILLER2','ZILLER3','ZILLER4'
                                      ,'ZILLER5','ZILLER6','ZILLER7','ZILLER8'
                                      ,'ZILLER9','ZILLERA'>
      01 ADDRESS     (A100/1:10) INIT <'ANGEL STREET 1','ANGEL STREET 2'
                                      ,'ANGEL STREET 3','ANGEL STREET 4'
                                      ,'ANGEL STREET 5','ANGEL STREET 6'
                                      ,'ANGEL STREET 7','ANGEL STREET 8'
                                      ,'ANGEL STREET 9','ANGEL STREET 10'>
      01 DATENATD (D/1:10)  INIT <D'1954-03-27',D'1954-03-27',D'1954-03-27'
                                  ,D'1954-03-27',D'1954-03-27',D'1954-03-27'
                                  ,D'1954-03-27',D'1954-03-27',D'1954-03-27'
                                  ,D'1954-03-27'>
      01 SALARY      (P4.2/1:10) INIT <1000,2000,3000,4000,5000
                                      ,6000,7000,8000,9000,9999>
      01 SALARY_N    (N4.2/1:10) INIT <1000,2000,3000,4000,5000
                                      ,6000,7000,8000,9000,9999>
      01 L§ADDRESS   (I2/1:10) INIT <14,14,14,14,14,14,14,14,14,15>
      01 N§ADDRESS   (I2/1:10) INIT <00,00,00,00,00,00,00,00,00,00>
      01 ROWS        (I4)
      01 INDEX       (I4)
      01 V1 VIEW OF NAT-DEMO_ID
      02 NAME
      02 ADDRESS     (EM=X(20))
      02 DATEOFBIRTH
      02 SALARY
      01 ROWCOUNT  (I4)
      END-DEFINE
      OPTIONS DB2ARRY=ON                  /* <-- ENABLE DB2 ARRAY
      ROWCOUNT := 10
      INSERT INTO NAT-DEMO_ID
             (NAME,ADDRESS,DATEOFBIRTH,SALARY)
             VALUES
             (:NAME(*),                   /* <-- ARRAY
              :ADDRESS(*)                 /* <-- ARRAY
              INDICATOR :N§ADDRESS(*)     /* <-- ARRAY
              LINDICATOR :L§ADDRESS(*),   /* <-- ARRAY DB2 VCHAR
              :DATENATD(1:10),            /* <-- ARRAY NATURAL DATES
              :SALARY_N(01:10)            /* <-- ARRAY NATURAL NUMERIC
             )
             FOR :ROWCOUNT ROWS
      SELECT * INTO VIEW V1 FROM NAT-DEMO_ID WHERE NAME > 'Z'
      DISPLAY V1                          /* <-- VERIFY INSERT
      END-SELECT
      BACKOUT
      END

## Fehlerbehandlung

Im Gegensatz zur normalen Natural-Fehlerbehandlung, bei der entweder ein `ON ERROR`-Statement verwendet wird, um Ausführungszeitfehler abzufangen, oder eine Standard-Fehlermeldung verarbeitet und die Programmausführung beendet wird, bietet die erweiterte Fehlerbehandlung von Natural for Db2 eine anwendungsgesteuerte Reaktion auf den aufgetretenen SQL-Fehler.

Zwei Natural-Subprogramme, `NDBERR` und `NDBNOERR`, werden bereitgestellt, um die übliche Natural-Fehlerbehandlung zu deaktivieren und den aufgetretenen SQL-Fehler auf den zurückgegebenen SQLCODE zu prüfen. Diese Funktionalität ersetzt die `E`-Funktion der `DB2SERV`-Schnittstelle, die weiterhin zur Verfügung steht, aber nicht mehr dokumentiert ist.

Weitere Informationen zu den Natural-Subprogrammen, die für Db2 zur Verfügung stehen, finden Sie im Abschnitt Interface-Subprogramme.

Beispiel:

    DEFINE DATA LOCAL
      01 #SQLCODE             (I4)
      01 #SQLSTATE            (A5)
      01 #SQLCA               (A136)
      01 #DBMS                (B1)
      END-DEFINE
      *
      *        Ignore error from next statement
      *
      CALLNAT 'NDBNOERR'
      *
      *        This SQL statement produces an SQL error
      *
      INSERT INTO SYSIBH-SYSTABLES (CREATOR, NAME, COLCOUNT)
        VALUES ('SAG', 'MYTABLE', '3')
      *
      *        Investigate error
      *
      CALLNAT 'NDBERR' #SQLCODE #SQLSTATE #SQLCA #DBMS
      *
      IF #DBMS NE 2                             /* not DB2
        MOVE 3700 TO *ERROR-NR
      END-IF
      *
      DECIDE ON FIRST VALUE OF #SQLCODE
        VALUE 0, 100                            /* successful execution
          IGNORE
        VALUE -803                              /* duplicate row
          /* UPDATE existing record
          /*
          IGNORE
        NONE VALUE
          MOVE 3700 TO *ERROR-NR
      END-DECIDE
      *
      END

### On this page

- Besondere Aspekte der speziellen Db2-Register
- Verwendung von nativen Natural DML-Statements
- Verwendung von Natural-SQL-Statements
- Verwendung von Natural-Systemvariablen
- Verarbeitung mehrerer Zeilen
- Fehlerbehandlung