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

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

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 READREAD-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

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

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_MONTHS
ASIN
ASCII
ASCII_CHR
ASCII_STR
ATAN
ATAN2
ATANH
BIGINT
BINARY
BLOB
CCSID_ENCODING
CEIL
CEILING
CHAR
CHARACTER_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
DEGREES
DIFFERENCE
DIGITS
DOUBLE
DOUBLE_PRECISION
DSN_XMLVALIDATE
EBCDIC_CHR
EBCDIC_STR
ENCRYPT_TDES
ENCRYPT
EXP
EXTRACT
FLOAT
FLOOR
GRAPHIC
GENERATE_UNIQUE
GETHINT
GETVARIABLE
HEX
HOUR

IDENTITY_VAL_LOCAL
IFNULL
INSERT
INTEGER
JULIAN_DAY
LAST_DAY
LCASE
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
POWER
QUANTIZE
QUARTER
RADIANS
RAISE_ERROR
RAND
REAL
REPEAT
REPLACE
RID
RIGHT
ROUND
ROUND_TIMESTAMP
ROWID
RPAD
RTRIM

SCORE
SECOND
SIGN
SIN
SINH
SMALLINT
SOAPHTTPC
SOAPHTTPV
SOAPHTTPNC
SOAPHTTPNV
SOUNDEX
SPACE
SQRT
STRIP
SUBSTR
SUBSTRING
TAN
TANH
TIME
TIMESTAMP
TIMESTAMPADD
TIMESTAMP_FORMAT
TIMESTAMP_ISO
TIMESTAMP_TZ
TO_CHAR
TO_DATE
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
COVARIANCE_SAMP
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 ENCODING SCHEME
CURRENT CLIENT_ACCNTG
CURRENT CLIENT_APPLNAME
CURRENT CLIENT_USERID
CURRENT CLIENT_WRKSTNNAME
CURRENT DATE
CURRENT_DATE
CURRENT DEBUG MODE
CURRENT DECFLOAT ROUNDING MODE
CURRENT DEGREE
CURRENT FUNCTION PATH
CURRENT_LC_CTYPE
CURRENT LC_CTYPE
CURRENT LOCALE LC_CTYPE
CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION
CURRENT_MEMBER
CURRENT OPTIMIZATION HINT
CURRENT PACKAGE PATH
CURRENT PACKAGESET
CURRENT_PATH
CURRENT PRECISION
CURRENT REFRESH AGE
CURRENT ROUTINE VERSION
CURRENT RULES
CURRENT SCHEMA
CURRENT SERVER
CURRENT SQLID
CURRENT TIME
CURRENT_TIME
CURRENT TIMESTAMP
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

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 INSERT-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:

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)

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

Beginn der AnweisungslisteUm 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

Beginn der AnweisungslisteUm 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