SELECT (SQL)

#### Search Results

Search

# SELECT (SQL)

Dieses Dokument behandelt folgende Themen:

- Funktion

- Syntax 1 − Cursor-orientierte Auswahl

- Syntax 2 - Nicht cursor-orientierte Auswahl

- Syntax-Element-Beschreibung

- Verknüpfungsabfragen (Join Query)

Eine Erläuterung der in dem Syntax-Diagramm verwendeten Symbole entnehmen Sie dem Abschnitt Syntax-Symbole.

Gehört zur Funktionsgruppe: Datenbankzugriffe und Datenbankänderungen

Siehe auch `SELECT` (SQL) im Teil Natural for Db2 in der Datenbankmanagementsystem-Schnittstellen-Dokumentation.

## Funktion

Das Natural SQL-Statement `SELECT` unterstützt sowohl das cursor-orientierte `SELECT`, mit dem eine beliebige Anzahl von Zeilen gelesen werden kann, als auch das nicht cursor-orientierte Singleton `SELECT`, das maximal eine Zeile liest. Mit dem Konstrukt `SELECT ... END−SELECT` verwendet Natural die gleiche Datenbankschleifenverarbeitung wie beim Natural-DML-Statement `FIND`.

Zwei verschiedene Strukturen sind möglich:

- Syntax 1 − Cursor-orientierte Auswahl

- Syntax 2 − Nicht cursor-orientierte Auswahl

## Syntax 1 − Cursor-orientierte Auswahl

Ebenso wie das Natural-DML-Statement `FIND` dient das cursor-orientierte `SELECT`-Statement dazu, auf der Basis eines Suchkriteriums einen Satz Zeilen (Datensätze) aus einer oder mehreren Db2-Tabellen auszuwählen. Da eine Datenbankverarbeitungschleife initiiert wird, muss die Schleife mit einem `LOOP`-Statement (im Reporting Mode) oder einem `END-SELECT`-Statement (im Structured Mode) abgeschlossen werden. Mit diesem Konstrukt verwendet Natural die gleiche Schleifenverarbeitung wie beim Natural-DML-Statement `FIND`.

Darüber hinaus braucht das Anwendungsprogramm keine Cursor-Verwaltung durchzuführen. Dies wird automatisch durch Natural erledigt.

- Syntax 1 - Common Set

- Syntax 1 - Extended Set

### Syntax 1 - Common Set

`SELECT` selection into-clause table-expression
|  | `UNION` `EXCEPT` `INTERSECT` |  |  | `DISTINCT` `ALL` |  |  | `(SELECT` selection table-expression`)` `SELECT` selection table-expression |  |  |
`[ORDER BY` criteria`]`
statement
| `END-SELECT` `LOOP` |  |

### Syntax 1 - Extended Set

`[WITH_CTE` common-table-expression, `]`
`SELECT` selection into-clause table-expression
|  | `UNION` `EXCEPT` `INTERSECT` |  |  | `DISTINCT` `ALL` |  |  | `(SELECT` selection table-expression`)` `SELECT` selection table-expression |  |  |
`[ORDER BY` criteria`]`
| `OPTIMIZE FOR` integer |  | `ROW` `ROWS` |  |  |  |  |
`[WITH` isolation-level`]`
`[SKIP LOCKED DATA]`
`[QUERYNO` integer`]`
`[OFFSET` row-count`]`
`[FETCH FIRST` row-limit`]`
`[WITH HOLD]`
`[WITH RETURN]`
`[WITH` scroll-mode`]`
`[WITH ROWSET POSITIONING FOR` max-rowsets`]`
`[IF NO RECORDS FOUND` instruction`]`
statement
| `END-SELECT` `LOOP` |  |  |

## Syntax 2 - Nicht cursor-orientierte Auswahl

Das `SELECT SINGLE`-Statement unterstützt die Funktionalität eines keine Cursor verwendenden Singleton Select, d.h., ein select-expression, der ohne Verwendung eines Cursors maximal eine Zeile liefert. Es kann nicht von einem Positioned `UPDATE`- oder einem `DELETE`-Statement referenziert werden.

- Syntax 2 - Common Set

- Syntax 2 - Extended Set

### Syntax 2 - Common Set

`SELECT SINGLE`
selection into-clause table-expression
`[``IF NO RECORDS FOUND` instruction`]`
statement
| `END-SELECT` `LOOP` |  |  |  |  |  |

### Syntax 2 - Extended Set

`SELECT SINGLE`
selection into-clause table-expression
`[``WITH` isolation-level`]`
`[``FETCH FIRST` row-limit`]`
`[``IF NO RECORDS FOUND` instruction`]`
statement
| `END-SELECT` `LOOP` |  |  |  |  |  |

## Syntax-Element-Beschreibung

Dieser Abschnitt beschreibt in alphabetischer Reihenfolge die Syntax-Elemente, die in den Syntax-Diagrammen unter Syntax 1 − Cursor-orientierte Auswahl und Syntax 2 - Nicht cursor-orientierte Auswahl dargestellt sind.

- END-SELECT | LOOP

- OFFSET row-count

- FETCH FIRST row-limit

- IF NO RECORDS FOUND instruction

- INTO-Klausel (into-clause)

- OPTIMIZE FOR integer ROWS

- ORDER BY criteria

- QUERYNO-Klausel

- selection

- SKIP LOCKED DATA

- statement

- table-expression

- UNION | EXCEPT | INTERSECT-Klausel

- WITH_CTE common-table-expression

- WITH HOLD-Klausel

- WITH isolation-level

- WITH RETURN-Klausel

- WITH scroll-mode

- WITH ROWSET POSITIONING FOR max-rowsets

### END-SELECT | LOOP

Im Structured Mode muss das für Natural reservierte Schlüsselwort `END-SELECT` zum Beenden des `SELECT`-Statements benutzt werden.

Im Reporting Mode muss das `LOOP`-Statement zum Beenden des `SELECT`-Statements benutzt werden.

### OFFSET row-count

`OFFSET` | [offset-row-count] |  | `ROW` `ROWS` |

Die `OFFSET`-Klausel gibt die Anzahl der Zeilen an, die in der Ergebnistabelle übersprungen werden sollen, bevor Zeilen von dort abgerufen werden. Eine begrenzte Anzahl von Zeilen am Ende einer Ergebnismenge (Result Set) kann bei Abfragen mit potenziell großen Ergebnismengen die Leistung verbessern.

offset-row-count ist eine numerische Variable oder Konstante, die die Anzahl der zu überspringenden Zeilen bestimmt. Die Zahl muss Null (`0`) oder eine positive Ganzzahl sein.

### FETCH FIRST row-limit

`FETCH FIRST` |  | `1` integer |  |  | `ROW` `ROWS` |  | `ONLY`

Die `FETCH FIRST`-Klausel begrenzt die Anzahl der mittels `FETCH` abzurufenden Zeilen. Es verbessert die Verarbeitungszeit von Abfragen mit möglicherweise großen Ergebnismengen, wenn nur eine beschränkte Anzahl von Zeilen erforderlich ist.

### IF NO RECORDS FOUND instruction

Anmerkung
Diese Klausel ist tatsächlich nicht Bestandteil von Natural SQL; sie stellt eine Natural-Funktion dar, die für SQL-Schleifenverarbeitung zur Verfügung gestellt wird.

#### Structured Mode-Syntax

`IF NO` [`RECORDS`] [`FOUND`] |
| `ENTER` |
statement
`END-NOREC`

#### Reporting Mode-Syntax

`IF NO` [`RECORDS`] [`FOUND`]
| `ENTER` |
statement
`DO` statement `DOEND`

Mit der `IF NO RECORDS FOUND`-Klausel können Sie eine Schleifen-Verarbeitung einleiten, die ausgeführt werden soll, falls kein Datensatz die im vorangegangenen `SELECT`-Statement angegebenen Selektionskriterien erfüllt.

Wenn kein Datensatz die angegebenen Selektionskriterien erfüllt, dann löst die `IF NO RECORDS FOUND`-Klausel eine Verarbeitungsschleife aus, die einmal mit einem "leeren" Datensatz durchlaufen wird. Falls Sie dies nicht wünschen, geben Sie in der `IF NO RECORDS FOUND`-Klausel das Statement `ESCAPE BOTTOM` an.

Enthält die `IF NO RECORDS FOUND`-Klausel ein oder mehrere Statements, werden diese unmittelbar ausgeführt, bevor die Schleife durchlaufen wird. Sollen vor Durchlaufen der Schleife keine Statements ausgeführt werden, muss die `IF NO RECORDS FOUND`-Klausel das Schlüsselwort `ENTER` enthalten

Anmerkung
Falls die Ergebnismenge des `SELECT`-Statements aus einer einzelnen Zeile mit NULL-Werten besteht, wird die `IF NO RECORDS FOUND`-Klausel nicht ausgeführt. Dies kann der Fall sein, wenn die Auswahlliste nur aus einer der `aggregate-functions` `SUM`, `AVG`, `MIN` oder `MAX` bei Spalten besteht, und die Menge, mit dem diese `aggregate-functions` operieren, leer ist. Bei obengenannter Verwendung dieser `aggregate-functions` sollten Sie daher keine `IF NO RECORDS FOUND`-Klausel benutzen, sondern stattdessen die Werte der betreffenden `NULL`-Indikator-Felder abfragen.

> Datenbankwerte

>   Natural setzt alle Datenbankfelder, die die in der aktuellen Verarbeitungsschleife angegebene Datei referenzieren, auf Leerwerte, es sei denn, eines der in der `IF NO RECORDS FOUND`-Klausel angegebenen Statements weist den Feldern andere Werte zu.

> Auswertung von Systemfunktionen

>   Natural-Systemfunktionen werden einmal für den leeren Datensatz ausgewertet, der für die aus der `IF NO RECORDS FOUND`-Klausel resultierende Verarbeitung erstellt wird.

### INTO-Klausel (into-clause)

`INTO` |  | parameter, `VIEW` {view-name [correlation-name ]}, |

In der `INTO`-Klausel geben Sie die Zielfelder im Programm an, die mit dem Auswahlergebnis gefüllt werden sollen.

Sie können in der `INTO`-Klausel entweder einzelne Parameter (`parameters`) oder eine oder mehrere im `DEFINE DATA`-Statement definierte Views (Datensichten) angeben.

Alle Zielfelder können entweder aus einer einzigen Tabelle kommen oder, bei einer Verknüpfungsoperation (vgl. Abschnitt Verknüpfungsabfragen (Join Query)), auch aus mehreren Tabellen.

Anmerkung
In der Standard-SQL-Syntax wird die `INTO`-Klausel nur bei Operationen ohne Cursor-Auswahl (Singleton `SELECT`) benutzt und kann nur dann angegeben werden, wenn eine einzelne Zeile ausgewählt werden soll. Dagegen wird in Natural die `INTO`-Klausel sowohl bei cursor-orientierten und nicht-cursor-orientierten Auswahloperationen verwendet.

Die Auswahl (`selection`) kann auch aus nur einem Stern (*) bestehen. In einem standardmäßigen `select-expression` steht dieser Stern für eine Liste aller Spaltennamen der in der `FROM`-Klausel angegebenen Tabelle(n). Im Natural-`SELECT`-Statement hat der Ausdruck `SELECT *` jedoch eine andere Bedeutung: Alle in der `INTO`-Klausel gemachten Angaben werden auch bei der Auswahl verwendet. Ihre Namen müssen vorhandenen Datenbank-Spaltennamen entsprechen.

Syntax-Element-Beschreibung:

Syntax-Element | Beschreibung
--- | ---
`parameter` | Wenn Sie einzelne Parameter als Zielfelder angeben, müssen diese in Anzahl und Format mit den in der entsprechenden Auswahl angegebenen Spalten (`columns`) bzw. Skalar-Ausdrücken (`scalar-expressions`) übereinstimmen, wie oben beschrieben. Siehe scalar-expressions und Beispiel 5.
`view-name` | Der Name einer Natural-View (Datensicht), so wie im `DEFINE DATA`-Statement definiert. Wenn in der `INTO`-Klausel eine oder mehrere Views (Datensichten) referenziert werden, muss die Anzahl der in der Auswahl gemachten Angaben der Anzahl der in der/den Views definierten Felder entsprechen (hierbei werden Gruppenfelder, redefinierte Felder und Indikatorfelder nicht mitgezählt). Anmerkung Die Natural-Zielfelder wie auch die Tabellenspalten müssen in einem Natural-DDM definiert sein (wobei ihre Namen allerdings unterschiedlich sein dürfen, da die Zuweisung entsprechend ihrer Reihenfolge erfolgt). Siehe Beispiel 5.
`correlation-name` | Wenn die `VIEW`-Klausel in einem `SELECT *` verwendet wird, in dem mehrere Tabellen mit einem `JOIN` verknüpft werden, sind `correlation-names` erforderlich, falls die angegebene View (Datensicht) Felder enthält, die Spalten referenzieren, welche in mehreren dieser Tabellen vorkommen. Um zu bestimmen, von welcher Spalte ausgewählt werden soll, werden bei der Generierung der Auswahlliste alle diese Spalten mit dem angegebenen `correlation-name` qualifiziert. Der einer View zugewiesene `correlation-name` muss einem der `correlation-names` entsprechen, mit denen die verknüpften Tabellen qualifiziert werden. Siehe auch Verknüpfungsabfragen (Join Query) und Beispiel 6.

> Beispiele

>   Beispiel 1:

>       DEFINE DATA LOCAL
>       01 PERS VIEW OF SQL-PERSONNEL
>         02 NAME
>         02 AGE
>       END-DEFINE
>       ...
>       SELECT *
>         INTO NAME, AGE

>   Beispiel 2:

>       ...
>       SELECT *
>         INTO VIEW PERS

>   Diese Beispiele sind gleichbedeutend mit den folgenden Beispielen:

>   Beispiel 3:

>       ...
>       SELECT NAME, AGE
>         INTO NAME, AGE

>   Beispiel 4:

>       ...
>       SELECT NAME, AGE
>         INTO VIEW PERS

>   Beispiel 5:

>       DEFINE DATA LOCAL
>       01 PERS VIEW OF SQL-PERSONNEL
>         02 NAME
>         02 AGE
>       END-DEFINE
>       ...
>       SELECT FIRSTNAME, AGE
>         INTO VIEW PERS
>         FROM SQL-PERSONNEL
>       ...

>   Die Zielfelder `NAME` und `AGE`, die Teil einer Natural-View (Datensicht) sind, erhalten den Inhalt der Datenbankspalten `FIRSTNAME` und `AGE`.

>   Beispiel 6:

>       DEFINE DATA LOCAL
>       01 PERS VIEW OF SQL-PERSONNEL
>         02 NAME
>         02 FIRST-NAME
>         02 AGE
>       END-DEFINE
>       ...
>       SELECT *
>         INTO VIEW PERS A
>         FROM SQL-PERSONNEL A, SQL-PERSONNEL B
>       ...

### OPTIMIZE FOR integer ROWS

`OPTIMIZE FOR` integer `ROWS`

Die `OPTIMIZE FOR integer ROWS`-Klausel wird verwendet, um Db2 im Voraus über die Anzahl an Ganzzahl-Zeilen zu informieren, die von der Ergebnistabelle eingelesen werden sollen. Ohne diese Klausel geht Db2 davon aus, dass alle Zeilen der Ergebnistabelle eingelesen werden sollen und führt dementsprechend eine Optimierung durch.

Diese optionale Klausel ist nützlich, wenn Sie wissen, wie viele Zeilen wahrscheinlich ausgewählt werden, weil eine Optimierung von Ganzzahl-Zeilen die Verarbeitungszeit verbessern kann, wenn die Anzahl der tatsächlich ausgewählten Zeilen nicht den Ganzzahlwert überschreitet (der im Bereich von `0` bis `2147483647` liegen kann).

> Beispiel

>       SELECT name INTO
>       #name FROM table WHERE AGE = 2 OPTIMIZE FOR 100 ROWS

### ORDER BY criteria

`ORDER BY` |  |  | sort-key |  | `ASC` |  |  | , |
`DESC`
`INPUT SEQUENCE`
`ORDER OF` table-designator

Die `ORDER BY`-Klausel sortiert die Ergebnismenge eines `SELECT`-Statement in einer bestimmten Reihenfolge.

Die Ergebnismenge kann nach Sortierschlüssel (`sort-key`), nach Eingabe-Reihenfolge (`INPUT SEQUENCE`) oder entsprechend der mit dem Tabellenbezeichner (`table-designator`) angegebenen Tabelle sortiert werden.

Syntax-Element-Beschreibung:

Syntax-Element | Beschreibung
--- | ---
`sort-key` | Zur Angabe eines Sortierschlüssels haben Sie folgende Möglichkeiten: Geben Sie eine Ganzzahl `n` an. Geben Sie an, dass die Sortierung durch Sortieren der Werte der `n`ten Zeile der Ergebnismenge erfolgt, oder, durch Angabe eines Spaltennamens, dass sie durch Sortieren der Werte der gegeben Spalte erfolgt. Geben Sie einen Skalar-Ausdruck an, wobei die Sortierung durch Sortieren der Werte des Ausdrucks erfolgt. Der Ausdruck kann aus Spalten der `host-variables` und Konstanten der Ergebnismenge bestehen. Falls mehrere Sortierschlüssel existieren, werden die Zeilen nach dem ersten Sortierschlüssel sortiert; doppelte, erste Sortierschlüssel werden nach dem zweiten Sortierschlüssel sortiert usw. Wird im Sortierschlüssel eines `FULLSELECT`, der einen `SET`-Operator (`UNION`, `EXCEPT`, `INTERSECTION`) enthält, ein Spaltenname angegeben, muss er nicht-qualifiziert sein.
`ASC|DESC` | Die in der `ORDER BY`-Klausel angegebene Reihenfolge kann entweder aufsteigend (`ASC`) oder absteigend (`DESC`) sein. Der Standardwert ist `ASC`. Siehe auch Beispiel 2 weiter unten.
`INPUT-SEQUENCE` | Gibt an, dass die Ergebnistabelle die Eingabe-Reihenfolge der Zeilen abbildet, die in der `VALUES`-Klausel eines `INSERT`-Statements angegeben sind.
`ORDER OF table-designator` | Gibt an, dass die Zeilen der Ergebnistabelle genauso wie bei der mit dem Tabellenbezeichner (`table-designator`) bezeichneten Tabelle sortiert werden sollen. Der `table-designator` muss außerdem in der `FROM`-Klausel angegeben werden.

> Beispiele

>   Beispiel 1:

>       DEFINE DATA LOCAL
>       1 #NAME          (A20)
>       1 #YEARS-TO-WORK (I2)
>       END-DEFINE
>       ...
>       SELECT NAME , 65 - AGE
>         INTO #NAME, #YEARS-TO-WORK
>         FROM SQL-PERSONNEL
>         ORDER BY 2
>         ...

>   Beispiel 2:

>       DEFINE DATA LOCAL
>       1 PERS VIEW OF SQL-PERSONNEL
>       1 NAME
>       1 AGE
>       1 ADDRESS   (1:6)
>       END-DEFINE
>       ...
>       SELECT NAME, AGE, ADDRESS
>         INTO VIEW PERS
>         FROM SQL-PERSONNEL
>         WHERE AGE = 55
>         ORDER BY NAME DESC
>         ...

### QUERYNO-Klausel

`QUERYNO` integer

Die `QUERYNO`-Klausel gibt die für dieses SQL-Statement zu benutzende Zahl bei der `EXPLAIN`-Ausgabe und der Ablaufverfolgung von Datensätzen an. Die Zahl wird als `QUERYNO`-Spalte in der `PLAN_TABLE` für die Zeilen benutzt, die Informationen zu diesem Statement enthalten.

### selection

Siehe Selection in Select Expressions.

### SKIP LOCKED DATA

`SKIP LOCKED DATA`

Die `SKIP LOCKED DATA`-Klausel gibt an, dass Zeilen übersprungen werden, wenn auf der betreffenden Zeile inkompatible Sperren durch andere Transaktionen vorliegen.

### statement

Das (oder die) Natural-Statement(s), die während der Verarbeitungsschleife ausgeführt werden sollen.

### table-expression

Siehe table-expression in Select Expressions.

### UNION | EXCEPT | INTERSECT-Klausel

| `UNION` `EXCEPT` `INTERSECT` |  |  | `DISTINCT` `ALL` |  |  | `(SELECT` selection table-expression`)` `SELECT` selection table-expression |  |

`UNION`, `EXCEPT` und `INTERSECT` leiten eine Abfrage ein, bei der `SET`-Operationen beteiligt sind.

`SET`-Operationen vereinigen die Ergebnisse von zwei oder mehr `select-expressions` miteinander. Die in den einzelnen `select-expressions` angegebenen Spalten müssen `SET`-operationskompatibel sein, d.h. in Anzahl, Typ und Format zueinander passen.

Nur der erste `select-expression` darf eine `INTO`-Klausel enthalten.

Syntax-Element-Beschreibung:

Syntax-Element | Beschreibung
--- | ---
`UNION` | Vereinigt die Ergebnisse von zwei oder mehr `select-expressions` miteinander.
`EXCEPT` | Gibt die Differenzmenge der Ergebnismengen zweier `select-expressions` an.
`INTERSECT` | Gibt die Schnittmenge zweier Ergebnismengen an.
`DISTINCT` | Gibt an, dass die Ergebnismenge keine redundanten (doppelten) Zeilen enthält. Dies ist die Standardeinstellung.
`ALL` | Gibt an, dass die Ergebnismenge redundante (doppelte) Zeilen enthält.Wenn die `SET`-Operation nicht ausdrücklich `ALL` enthält, werden redundante (doppelte) Zeilen aus dem Ergebnis entfernt.

> Beispiel

>       DEFINE DATA LOCAL
>       01 PERS VIEW OF SQL-PERSONNEL
>         02 NAME
>         02 AGE
>         02 ADDRESS (1:6)
>       END-DEFINE
>       ...
>       SELECT NAME, AGE, ADDRESS
>         INTO VIEW PERS
>         FROM SQL-PERSONNEL
>         WHERE AGE > 55
>       UNION ALL
>       SELECT NAME, AGE, ADDRESS
>         FROM SQL-EMPLOYEES
>         WHERE PERSNR < 100
>       ORDER BY NAME
>       ...
>       END-SELECT
>       ...

### WITH_CTE common-table-expression

`WITH_CTE` common-table-expression-name [(column-name,…)] `AS` (fullselect)

Mit dieser Klausel können Sie eine Ergebnistabelle definieren, die in einer beliebigen `FROM`-Klausel eines nachfolgenden `SELECT`-Statements referenziert werden kann.

Syntax-Element-Beschreibung:

Syntax-Element | Beschreibung
--- | ---
`WITH_CTE` | Das Natural-spezifische Schlüsselwort `WITH_CTE` entspricht dem SQL-Schlüsselwort `WITH`. `WITH_CTE` wird durch den Natural Compiler in das SQL-Schlüsselwort `WITH` umgesetzt.
`common-table-expression-name` | Muss eine nicht qualifizierte SQL-Kennung sein und muss sich von anderen, im selben Statement angegebenen `common-table-expression` unterscheiden. Nach dem Schlüsselwort `WITH_CTE` können mehrere `common-table-expressions` angegeben werden. Jeder dieser Ausdrücke kann in der `FROM`-Klausel eines `common-table-expression-name` des nachfolgenden `SELECT`-Statements referenziert werden.
`column-name` | Muss eine nicht qualifizierte SQL-Kennung sein und muss innerhalb eines `common-table-expression-name` eindeutig sein.
`AS (fullselect)` | Die Anzahl der `column-names` muss gleich der Anzahl der Spalten des `fullselect` sein.

Ein `common-table-expression` kann in folgenden Fällen benutzt werden

- anstelle einer View (Datensicht), um das Erstellen einer View zu vermeiden,

- wenn dieselbe Ergebnistabelle gemeinsam in einem `fullselect` verwendet werden muss,

- wenn die Ergebnistabelle durch Rekursion abgeleitet werden muss.

Rekursive Abfragen sind in Anwendungen wie zum Beispiel Stücklisten von Nutzen.

> Beispiel

>       WITH_CTE
>        RPL (PART,SUBPART,QUANTITY) AS
>        (SELECT ROOT.PART,ROOT.SUBPART,ROOT.QUANTITY
>           FROM HGK-PARTLIST ROOT
>          WHERE ROOT.PART ='01'
>         UNION ALL
>         SELECT CHILD.PART,CHILD.SUBPART,CHILD.QUANTITY
>           FROM  RPL PARENT, HGK-PARTLIST CHILD
>           WHERE PARENT.SUBPART = CHILD.PART
>         )
>       SELECT DISTINCT PART,SUBPART,QUANTITY
>         INTO VIEW V1
>         FROM RPL
>         ORDER BY PART,SUBPART,QUANTITY
>       END-SELECT

### WITH HOLD-Klausel

`WITH HOLD`

Die `WITH HOLD`-Klausel wird benutzt, um zu verhindern, dass der Cursor durch eine `COMMIT`-Operation innerhalb von Datenbankschleifen geschlossen wird. Wenn `WITH HOLD` angegeben wird, schreibt eine `COMMIT`-Operation alle Änderungen der aktuellen logischen Arbeitseinheit weg, gibt aber nur die Sperren frei, die nicht zur Verwaltung des Cursors erforderlich sind. Diese optionale Klausel ist hauptsächlich nützlich bei der Stapelverarbeitung, sie wird ignoriert im pseudo-konversationalen CICS-Modus und in nachrichtengesteuerten IMS-Programmen.

> Beispiel

>       SELECT name INTO #name FROM table
>       WHERE AGE = 2 WITH HOLD

### WITH isolation-level

`WITH` |  | `CS` `RR` `RR KEEP UPDATE LOCK` `RS` `RS KEEP UPDATE LOCKS` `UR` |

Mit dieser optionalen Klausel können Sie eine explizite Isolationsstufe angeben, mit der das Statement ausgeführt werden soll.

Folgende Optionen stehen zur Verfügung:

Option | Bedeutung
--- | ---
`CS` | Cursorstabilität
`RR` | Wiederholbares Lesen
`RR KEEP UPDATE LOCKS` | Wiederholbarer Lesevorgang unter Beibehaltung von Aktualisierungssperren. Gilt nur bei Syntax 1 - Extended Set und nur, wenn ein positioniertes `UPDATE`-Statement oder ein positioniertes `DELETE`-Statement mit dem `SELECT`-Statement verarbeitet wird.
`RS` | Lesestabilität
`RS KEEP UPDATE LOCKS` | Lesestabilität unter Beibehaltung von Aktualisierungssperren. Gilt nur bei Syntax 1 - Extended Set und nur, wenn ein positioniertes `UPDATE`-Statement oder ein positioniertes `DELETE`-Statement mit dem `SELECT`-Statement verarbeitet wird.
`UR` | Nicht festgeschriebener Lesevorgang `UR` kann nur bei einem `SELECT`-Statement angegeben werden, und wenn es für die Tabelle nur eine Lesezugriffsberechtigung gibt. Die standardmäßige Isolationsstufe wird durch Isolation des Pakets oder Plans festgelegt, worindas Statement eingebunden ist. Die standardmäßige Isolationsstufe ist außerdem abhängig davon, ob für die Ergebnistabelle nur eine Lesezugriffsberechtigung besteht oder nicht. Um die standardmäßige Isolationsstufe zu ermitteln, greifen Sie auf die IBM-Literatur zurück.

### WITH RETURN-Klausel

`WITH RETURN`

Die `WITH RETURN`-Klausel dient zum Erstellen von Ergebnismengen. Deshalb gilt diese Klausel nur für Programme, die als eine Natural Stored Procedure eingesetzt werden. Wenn die `WITH RETURN`-Klausel in einem `SELECT`-Statement angegeben wird, bleibt der zugrundeliegende Cursor offen, wenn die zugehörigeVerarbeitungsschleife verlassen wird, außer wenn die Verarbeitungsschleife alle Zeilen der Ergebnismenge selbst gelesen hatte. Während der ersten Ausführung der Verarbeitungsschleife wird nur der Cursor geöffnet. Die erste Zeile wird noch nicht abgerufen. Dadurch wird es dem Natural-Programm ermöglicht, eine vollständige Ergebnismenge an den Aufrufer der Stored Procedure zurückzugeben. Es bleibt dem Natural-Programmierer überlassen, wie viele Zeilen der Natural Stored Procedure abgearbeitet werden und wie viele nicht abgearbeitete Zeilen der Ergebnismenge an den Aufrufer der Stored Procedure zurückgegeben werden. Wenn Sie Zeilen der `WITH RETURN`-Operation in der Natural Stored Procedure verarbeiten möchten, müssen Sie folgende Codezeilen eingeben, um zu verhindern, dass die "erste leere" Zeile in der Verarbeitungsschleife verarbeitet wird.

    IF *counter =1 ESCAPE TOP END-IF

Wenn Sie sich entschließen, die Verarbeitung der Zeilen zu beenden, müssen Sie folgende Codezeilen in der Verarbeitungsschleife eingeben:

    IF condition ESCAPE BOTTOM END-IF

Wenn das Programm alle Zeilen der Ergebnismenge liest, wird der Cursor geschlossen, und es wird keine Ergebnismenge für dieses `SELECT WITH RETURN` an den Aufrufer der Stored Procedure zurückgegeben.

Die folgenden Programme sind Beispiele zum Einlesen vollständiger Ergebnismengen (Beispiel 1) und unvollständiger Ergebnismengen (Beispiel 2).

> Beispiele

>   Beispiel 1:

>       DEFINE DATA LOCAL
>       . . .
>       END DEFINE
>       *
>       *  Return all rows of the result set
>       *
>       SELECT * INTO VIEW V2
>                           FROM SYSIBM-SYSROUTINES
>                           WHERE RESULT_SETS > 0
>                           WITH RETURN
>       ESCAPE BOTTOM
>       END-SELECT
>       END

>   Beispiel 2:

>       DEFINE DATA LOCAL
>       . . .
>       END DEFINE
>       *
>       *  Read the first two rows and return the rest as result set
>       *
>       SELECT * INTO VIEW V2
>                           FROM SYSIBM-SYSROUTINES
>                           WHERE RESULT_SETS > 0
>                           WITH   RETURN
>       WRITE PROCEDURE *COUNTER
>       IF *COUNTER = 1 ESCAPE TOP END-IF
>       IF *COUNTER = 3 ESCAPE BOTTOM END-IF
>       END-SELECT
>       END

### WITH scroll-mode

`WITH` |  | `ASENSITIVE SCROLL` `INSENSITIVE SCROLL` `SENSITIVE STATIC SCROLL` `SENSITIVE DYNAMIC SCROLL` |  | [:] scroll_hv [`GIVING` [:] sqlcode]

Natural for Db2 unterstützt verschiebbare Cursor von Db2 über die Klauseln `WITH ASENSITIVE SCROLL`, `WITH SENSITIVE STATIC SCROLL` und `SENSITIVE DYNAMIC SCROLL`.

Verschiebbare Cursor ermöglichen es Natural for Db2-Anwendungen, eine Zeile in einer Ergebnismenge beliebig zu positionieren. Mit nicht verschiebbaren Cursor können die Daten nur sequenziell vom oben nach unten gelesen werden.

Verschiebbare Cursor ermöglichen es der Anwendungen, eine beliebige Zeile in einem Cursor zu positionieren, solange der Cursor offen ist.

Die Positionierung erfolgt in Abhängigkeit vom `scroll_hv`-Inhalt. Der Inhalt wird jedes Mal ausgewertet, wenn eine `FETCH`-Operation gegen Db2 ausgeführt wird.

Syntax-Element-Beschreibung:

Syntax-Element | Beschreibung
--- | ---
`ASENSITIVE SCROLL` | Gibt an, dass der Cursor entweder `INSENSITIVE` oder `SENSITIVE DYNAMIC` ist. Dies wird von Db2 beim Öffnen des Cursor in Abhängigkeit von `READ-ONLY`-Eigenschaft des Cursor bestimmt: Wenn über den Cursor nur gelesen werden kann (d.h. `READ-ONLY`), wird er `INSENSITIVE`, wenn der Cursor nicht `READ-ONLY` ist, wird er `SENSITIVE DYNAMIC`.
`INSENSITIVE SCROLL` | Gibt an, dass der Cursor `INSENSITIVE` ist bei Aktualisierungen, Löschungen und Einfügungen, die gegen die Basistabelle ausgeführt werden. `INSENSITIVE SCROLL` bezieht sich auf einen Cursor, der nicht in Positioned `UPDATE`- oder Positioned `DELETE`-Operationen benutzt werden kann. Außerdem gibt ein `INSENSITIVE SCROLL`-Cursor keine `UPDATE`-, `DELETE`- oder `INSERT`-Operationen gegen die Basistabelle wieder, nachdem der Cursor geöffnet wurde. Siehe auch Anmerkung.
`SENSITIVE STATIC SCROLL` | Gibt an, dass der Cursor `SENSITIVE` ist bei Aktualisierungen und Löschungen, die gegen die Basistabelle ausgeführt werden, jedoch gegen Einfügungen, nachdem der Cursor geöffnet worden ist. `SENSITIVE STATIC SCROLL` bezieht sich auf einen Cursor, der für Positioned `UPDATE`- oder Positioned `DELETE`-Operationen benutzt werden kann. Außerdem gibt ein `SENSITIVE STATIC SCROLL`-Cursor `UPDATE` und `DELETE`-Operationen an Zeilen der Basistabelle wieder. Der Cursor gibt keine `INSERT`-Operationen wieder. Siehe auch Anmerkung.
`SENSITIVE DYNAMIC SCROLL` | `SENSITIVE DYNAMIC` gibr an, dass der Cursor `SENSITIVE` ist bei Aktualisierungen, Löschungen und Einfügungen, die gegen die Basistabelle ausgeführt werden, nachdem der Cursor geöffnet worden ist. `SENSITIVE DYNAMIC` verschiebbare Cursor geben `UPDATE`-, `DELETE`- und `INSERT`-Operationen gegen die Basistabelle wieder, während der Cursor geöffnet ist.

Anmerkung:
`INSENSITIVE` und `SENSITIVE STATIC` verschiebbare Cursor verwenden temporäre Ergebnistabellen und benötigen eine TEMP-Datenbank in Db2 (siehe entsprechende IBM Db2 Literatur).

> scroll_hv

>   Die Variable `scroll_hv` muss alphanumerisch sein.

>   Die Variable `scroll_hv` gibt an, welche Zeile der Ergebnistabelle während einer Ausführung der Datenbank-Verarbeitungsschleife abgerufen wird. Außerdem gibt sie während einer `FETCH`-Operation die Sensitivität von `UPDATE`- oder `DELETE`-Operationen gegen die Zeile der Basistabelle an. Der Inhalt der Variablen `scroll_hv` wird jedesmal ausgewertet, wenn der Datenbank-Verarbeitungsschleifenzyklus ausgeführt wird.

>   | `INSENSITIVE` `SENSITVE` |  |  | `AFTER` `BEFORE` `CURRENT` `FIRST` `LAST` `PRIOR` `NEXT` |
>   | `ABSOLUTE` `RELATIVE` |  |  | `+` `-` |  | integer

> scroll_hv-Sensitivitätsangabe

>   Die Sensitivitätsangabe `INSENSITIVE` oder `SENSITIVE` ist optional.

>   - Wenn sie bei einem `FETCH` gegen einen `INSENSITIVE SCROLL`-Cursor weggelassen wird, gilt der Standardwert `INSENSITIVE`.

>   - Wenn sie bei einem `FETCH` gegen einen `SENSITIVE STATIC`/`DYNAMIC SCROLL`-Cursor weggelassen wird, gilt der Standardwert `SENSITIVE`.

>   Die Sensitivität gibt an, ob die Zeilen in der Basistabelle überprüft werden oder nicht, wenn eine `FETCH`-Operation für einen verschiebbaren Cursor ausgeführt wird.

>   - Wenn die entsprechende Basistabellen-Spalte für die `WHERE`-Klausel qualifiziert ist und nicht gelöscht wurde, gibt ein `SENSITIVE FETCH` die Zeile der Basistabelle zurück.

>   - Wenn die entsprechende Basistabellen-Spalte nicht für die `WHERE`-Klausel qualifiziert ist oder nicht gelöscht wurde, gibt `SENSITIVE FETCH` einen Status "freier Datenbereich durch Aktualisieren" (UPDATE-Hole) oder "freier Datenbereich durch Löschen" (DELETE-Hole), d.h. `SQLCODE +222`, zurück.

>   Ein `INSENSITIVE FETCH` überprüft nicht die betreffende Basistabellen-Spalte.

> scroll_hv-Optionen

>   Im Folgenden werden die verfügbaren Optionen erläutert, um die abzurufende(n) Zeile(n), die Position, von der aus der `FETCH` gestartet werden soll und/oder die Richtung, in der geblättert werden soll, festzulegen:

>   Option | Erläuterung
>   --- | ---
>   `AFTER` | Positioniert nach der letzten Zeile. Es wird keine Zeile abgerufen.
>   `BEFORE` | Positioniert vor der ersten Zeile. Es wird keine Zeile abgerufen.
>   `CURRENT` | Ruft die aktuelle Zeile (erneut) ab.
>   `FIRST` | Ruft die erste Zeile ab.
>   `LAST` | Ruft die letzte Zeile ab.
>   `NEXT` | Ruft die Zeile nach der aktuellen Zeile ab. Dies ist der Standardwert.
>   `PRIOR` | Ruft die Zeile vor der aktuellen Zeile ab.
>   `+|-integer` | Gilt nur in Verbindung mit `ABSOLUTE` oder `RELATIVE`. Gibt die Position der abzurufenden Zeile absolut (`ABSOLUTE`) oder relativ (`RELATIVE`) an. Geben Sie ein Plus- (+) oder Minus-Zeichen (-) und danach eine Ganzzahl ein. Der Standardwert ist ein Plus-Zeichen (+).
>   `ABSOLUTE` | Gilt nur in Verbindung mit `+|-integer`. Benutzt `integer` als die absolute Position innerhalb des Resultset (Ergebnismenge), von dem aus die Zeile abgerufen wird. Weitere Einzelheiten hinsichtlich positiver und negativer Positionszahlen entnehmen Sie der Db2 SQL Reference-Dokumentation von IBM.
>   `RELATIVE` | Gilt nur in Verbindung mit `+|-integer`. Benutzt `integer` als Position relativ zur aktuellen Position innerhalb des Resultset (Ergebnismenge), von dem aus die Zeile abgerufen wird. Weitere Einzelheiten hinsichtlich positiver und negativer Positionszahlen entnehmen Sie der Db2 SQL Reference-Dokumentation von IBM.

> GIVING [:] sqlcode

>   Die Angabe von `GIVING [:] sqlcode` ist optional. Falls angegeben, muss die Natural-Variable `[:] sqlcode` das Format I4 haben. Die Werte für diese Variable werden vom Db2 `SQLCODE` der zugrundeliegenden `FETCH`-Operation zurückgegeben. Dadurch wird es der Anwendung ermöglicht, auf verschiedene, bei geöffnetem verschiebbarem Cursor vorgefundene Status-Codes zu reagieren. Die wichtigsten, von `SQLCODE` angezeigten Status-Codes sind in der folgenden Tabelle aufgeführt:

>   SQLCODE | Erläuterung
>   --- | ---
>   `0` | `FETCH`-Operation erfolgreich, Daten zurückgegeben, außer bei einem `FETCH` mit der Option `BEFORE` oder `AFTER`.
>   `+100` | Zeile nicht gefunden, Cursor noch geöffnet, keine Daten zurückgegeben.
>   `+222` | Freier Datenbereich durch Aktualisieren (`UPDATE`-Hole) oder freier Datenbereich durch Löschen (`DELETE`-Hole), Cursor noch geöffnet, keine Daten zurückgegeben. Die entsprechende Zeile der Basistabelle wurde aktualisiert oder gelöscht, so dass die Zeile nicht mehr für die `WHERE`-Klausel qualifiziert ist.
>   `+231` | `FETCH`-Operation mit der Option `CURRENT`, wobei der Cursor aber nicht auf einer Zeile positioniert ist, keine Daten zurückgegeben. Diese Situation entsteht, wenn das vorangegangene `FETCH` den `SQLCODE +100` zurückgegeben hat.

>   Wenn Sie `GIVING [:] sqlcode` angeben, muss die Anwendung auf die verschiedenen Status-Codes reagieren. Wenn ein `SQLCODE +100` fünfmal hintereinander ohne Terminal-Ein-/Ausgabe auftritt, gibt die Natural für Db2-Laufzeitumgebung den Natural-Fehler NAT3296 aus, um Anwendungsschleifen zu verhindern. Die Anwendung kann die Verarbeitungsschleife durch Ausführen eines `ESCAPE`-Statements beenden.

>   Wenn Sie `GIVING [:] sqlcode` nicht angeben, erzeugt, außer bei `SQLCODE 0` und `SQLCODE +100`, jeder `SQLCODE` den Natural-Fehler NAT3700, und die Verarbeitungsschleife wird beendet. Ein `SQLCODE +100` (Zeile nicht gefunden) beendet die Verarbeitungsschleife.

>   Siehe auch Beispielprogramm `DEM2SCRL` in der Natural-Systembibliothek `SYSDB2`.

### WITH ROWSET POSITIONING FOR max-rowsets

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

Diese Klausel ermöglich eine Verarbeitung von Db2-Zeilengruppen, die der Multifetch-Verarbeitung in der Natural-DML entspricht. `[:] row_hv (I4)` oder `integer` bestimmt die maximale Anzahl Zeilen, die von Db2 an Natural zurückgegeben werden. Die Zahl bestimmt entweder die Größe des Natural Multi-Fetch-Puffers, der für die Standardverarbeitung von mehreren Zeilen benutzt wird, oder die maximale Anzahl Zeilen, die von Db2 an das Natural-Programm für die erweiterte Verarbeitung mehrerer Zeilen zurückgegeben wird.

> ROWS_RETURNED [:] ret_row-Klausel:

>   Mit dieser Klausel wir eine Variable im Format I4 angegeben, die die Anzahl der Zeilen empfängt, die von Db2 aufgrund der zuletzt ausgeführten Db2-Abrufoperation für die erweiterte Verarbeitung mehrerer Zeilen zurückgegeben wird.

## Verknüpfungsabfragen (Join Query)

Eine Verknüpfungsabfrage (Join Query) ist eine Abfrage, bei der Daten aus mehr als einer Tabelle gewonnen werden. Alle beteiligten Tabellen müssen in der `FROM`-Klausel angegeben werden.

Eine Verknüpfungsabfrage bildet immer das kartesische Produkt der in der `FROM`-Klausel aufgelisteten Tabellen und entfernt später aus dieser kartesischen Produkttabelle alle Zeilen, die nicht die Verknüpfungsbedingung erfüllen, die in der `WHERE`-Klausel angegeben ist.

Falls die Tabellennamen ziemlich lang sind, können Sie Korrelationsnamen (`correlation-name`) verwenden, um sich Schreibarbeit zu ersparen. Korrelationsnamen müssen benutzt werden, wenn eine in der Auswahlliste angegebene Spalte in mehr als einer der zu verknüpfenden Tabellen existiert, damit klar ist, welche der namensgleichen Spalten ausgewählt werden sollen.

### Beispiel

    DEFINE DATA LOCAL
    1 #NAME     (A20)
    1 #MONEY    (I4)
    END-DEFINE
    ...
    SELECT NAME, ACCOUNT
      INTO #NAME, #MONEY
      FROM  SQL-PERSONNEL P, SQL-FINANCE F
      WHERE P.PERSNR = F.PERSNR
        AND F.ACCOUNT > 10000
        ...

### On this page

- Funktion
- Syntax 1 − Cursor-orientierte Auswahl
- Syntax 2 - Nicht cursor-orientierte Auswahl
- Syntax-Element-Beschreibung
- Verknüpfungsabfragen (Join Query)