Überlegungen zu 'replace' mit SQL

Im Kontext von SQL stellt die EGL-Anweisung 'replace' überarbeitete Informationen aus einer SQL-Datensatzvariablen zurück in eine Zeile in einer relationalen Datenbank.

Die Anweisung erstellt eine SQL-Anweisung UPDATE im generierten Code. EGL kann diese Anweisung implizit auf Basis von Informationen und Eigenschaften in Ihrer SQL-Datensatzvariablen erstellen, oder Sie können expliziten SQL-Code in die Anweisung 'replace' einbetten, indem Sie die Direktive '#sql' verwenden (siehe sql (Direktive)).

Bevor Sie die Anweisung 'replace' verwenden, müssen Sie eine Zeile für die nachfolgende Ersetzungsoperation abrufen. Hierzu haben Sie zwei Möglichkeiten:

Syntax

Syntaxdiagramm für die Anweisung 'replace'
SQL-Datensatzvariable
Verweist auf einen Speicherbereich, in den Sie die aktualisierten Informationen gestellt haben. EGL verwendet diese Informationen zum Aktualisieren einer einzelnen Datenbankzeile.
dynamische_SQL-Feldgruppe
Diese Variable benennt eine dynamische Feldgruppe, die sich aus SQL-Datensatzvariablen zusammensetzt. Die EGL-Anweisung 'replace ' aktualisiert die gesamte dynamische Feldgruppe. In der Anweisung 'replace ' muss with #sql{expliziter_Code} verwendet werden. Die Cursorposition muss mithilfe einer Anweisung 'open' oder 'get position' erstellt worden sein.
Element_in_dynamischer_SQL-Feldgruppe
Sie können ein Element einer dynamischen Feldgruppe angeben. Mit der EGL-Anweisung 'replace' wird die angegebene Zeile in der dynamischen Feldgruppe aktualisiert. Die Cursorposition muss mithilfe einer Anweisung 'open' oder 'get position' erstellt worden sein.
SQL-Anweisung
Eine eingebettete SQL-Anweisung UPDATE zum Ersetzen der von EGL ansonsten generierten impliziten SQL-Anweisung UPDATE. Zwischen der Direktive '#sql' und der linken geschweiften Klammer darf kein Leerzeichen stehen.
Optionen_für_'replace'
Wenn EGL impliziten SQL-Code für Sie generieren soll, können Sie die Ausgabe mithilfe der folgenden Optionen beeinflussen:
cursor
Diese Option weist EGL an, eine Klausel vom Typ WHERE CURRENT OF Cursor-ID zu erstellen. Damit dies funktioniert, müssen Sie eine Ergebnismenge mithilfe einer Anweisung 'get' oder 'open' erstellt haben, da EGL keinen direkten Zugriff auf den Cursor bereitstellt, der von diesen Anweisungen erstellt wird. EGL verwendet den Namen der SQL-Datensatzvariablen, um diese Cursor-ID zu suchen. Diese Option ist die Standardoption.
nocursor
Diese Option generiert eine Standardklausel WHERE. Darüber hinaus müssen Sie entweder eine explizite SQL-Anweisung angeben oder einen Datensatz, der die Eigenschaft 'keyItems' einschließt. Für die Auswertung dürfen Sie 'nocursor' und 'usingKeys' nicht in derselben Anweisung angeben.
usingKeys
Sie können hier Feldnamen aus 'SQL-Datensatzvariable' angeben, um die Schlüsselfelder zu überschreiben, die Sie in dieser Datensatzdefinition angegeben haben. Diese Option liefert die Bedingungen für eine SQL-Klausel WHERE, indem die Felder aus 'SQL-Datensatzvariable' angegeben werden. Diese Felder müssen mit den entsprechenden Spalten in den zu ersetzenden Datenbankzeilen übereinstimmen. Beachten Sie, dass die Schlüsselelemente aus der Liste der Spalten, die in der SET-Klausel aktualisiert werden, ausgeschlossen werden.
Anmerkung: Bei Multiple-Row-Operationen wird 'usingKeys' von EGL nicht unterstützt.
from Ergebnismengen-ID
Sie müssen die Ergebnismengen-ID aus einer vorherigen EGL-Anweisung 'get' oder 'open' angeben, wenn die folgenden Bedingungen zutreffen:
  • Sie haben eingebettete SQL-Anweisungen (mithilfe der Direktive '#sql') verwendet, um die Ergebnismenge zu erstellen.
  • Dieser Code hat andere Gruppen von Spalten für die Aktualisierung abgerufen als die Gruppen in der impliziten SQL-Anweisung, die von EGL generiert wurde.
Anders ausgedrückt: Wenn Sie nicht mit der Standardergebnismenge arbeiten, die EGL normalerweise für diese SQL-Datensatzvariable erstellt, geben Sie eine Ergebnismengen-ID an.

Implizite SQL-Anweisung

Standardmäßig hat eine Anweisung 'replace', die einen SQL-Datensatz schreibt, die folgenden Auswirkungen:
  • Infolge der Zuordnungen zwischen Datensatzfeldern und SQL-Tabellenspalten in der Datensatzabschnittsdeklaration kopiert der generierte Code die Daten aus den einzelnen Feldern in die jeweils zugehörige SQL-Tabellenspalte.
  • Wenn Sie ein Feld als Schlüsselelement oder als schreibgeschützt definiert haben, bleibt der Wert in der Spalte, die diesem Feld entspricht, unverändert.
Die SQL-Anweisung weist standardmäßig die folgenden Merkmale auf:
  • Die implizite SQL-Anweisung UPDATE schließt keine Felder ein, die als Schlüsselelemente oder als schreibgeschützt definiert sind.
  • Die implizite SQL-Anweisung UPDATE für einen bestimmten Datensatz ist mit der folgenden Anweisung vergleichbar:
    UPDATE Tabellenname
    SET    Spalte01 = :mein_Feld01,
           Spalte02 = :mein_Feld02,
            ...
           SpalteNN = :mein_FeldNN    
    WHERE CURRENT OF Cursor

Beispiel

Der folgende Code schließt die Anweisung 'replace' ein. Der Code stammt aus dem vollständigen SQL-Programm, das Sie unter EGL-SQL-Beispielprogramm vorfinden.

  try
    get dept forupdate;
    dept.description = "Test Engineers";
    replace dept;
    commit();
  onException(sqlEx SQLException)
    sqlFailure();     
  end 

Das folgende Beispiel zeigt die Anweisung 'replace' für eine Multiple-Row-Operation:

employees Employee[0]{rowsetsize=10};
Open resultset1 forUpdate with #sql{ 
    select eID, uName, PASSWORD, fName, lName, office, sex, EMail
    from EMPLOYEETEST
} for employees;
Get Next employees;

//Hierduch wird die zweite Zeile in der Zeilengruppe mit aktuellem Inhalt aktualisiert
employees[2].uName = “test”;
Replace employees[2]; 

//Hierduch wird die zweite Zeile in der Zeilengruppe mit einer expliziten Variablen aktualisiert
newName CHAR(20) = “test1”;
Replace employees[2]
         #with SQL{ update EMPLOYEETEST 
                    set uName = :newName }; 

// Der Index kann eine Variable sein
i int = 2;
Replace employees[i]; 

//Hierdurch werden alle Zeilen in der Zeilengruppe mit 'uName = "test"' aktualisiert
//Es muss explizites SQL verwendet werden, da ansonsten ein 
//Gültigkeitsfehler auftritt. 
uName CHAR(10) = “test”;
Replace employees 
        #with SQL{ update EMPLOYEETEST  
                   set uName = :uName };

Fehlerbedingungen

Wenn Sie eine Anweisung 'replace' verwenden, sind unter anderem die folgenden Bedingungen ungültig:
  • Sie betten eine SQL-Anweisung eines anderen Typs als UPDATE in die Direktive '#sql' ein.
  • Sie geben einige, aber nicht alle Klauseln einer SQL-Anweisung UPDATE in Ihrem eingebetteten Code an.
  • Sie geben keine Ergebnismengen-ID an, wenn Sie nicht mit einer Standardergebnismenge arbeiten. Weitere Informationen finden Sie unter 'Syntax' in diesem Thema.
  • Sie geben eine eingebettete Anweisung UPDATE an (oder Sie akzeptieren eine implizite Anweisung UPDATE), die eines der folgenden Merkmale aufweist:
    • Sie aktualisiert mehrere Tabellen.
    • Sie ist einer Spalte zugeordnet, die entweder nicht vorhanden ist oder die mit der zugehörigen Hostvariablen nicht kompatibel ist.
  • Sie geben eine SQL-Datensatzvariable an, in der alle Felder schreibgeschützt sind.

Kompatibilität

Tabelle 1. Hinweise zur Kompatibilität für 'replace'
Plattform Problem
COBOL-Generierung In COBOL wird die beste Leistung erzielt, wenn stets die Klausel 'from Ergebnismenge' in die Anweisung 'replace' eingeschlossen wird.
SQL Server Die Anweisungen 'delete last' und 'get last' für Multiple-Row-Funktionen können nicht zusammen verwendet werden. Die Ergebnismenge wird geschlossen, wenn beide Anweisungen einmal ausgeführt werden.
DB2 for i5/OS Die Journalfunktion muss aktiviert sein, oder 'transaction isolation=none' muss der Verbindungszeichenfolge hinzugefügt werden.

Feedback