Feldverweise in ESQL

In diesem Kapitel wird die Verwendung von ESQL-Feldverweisen für die Erstellung von Pfaden zu Nachrichtentextelementen beschrieben.

Die vollständige Syntax für Feldverweise lautet wie folgt:

Ein Feldverweis besteht aus einem Korrelationsnamen gefolgt von keinem oder mehreren Pfadfeldern, die durch Punkte (.) voneinander getrennt sind. Der Korrelationsname gibt einen anerkannten Ausgangspunkt an und muss dem Namen einer Konstante, einer deklarierten Variablen (skalar, Zeile oder Referenz) oder einem der vordefinierten Ausgangspunkte entsprechen, z. B. InputRoot (Eingabestamm). Die Pfadfelder definieren einen Pfad vom Ausgangspunkt zu dem gewünschten Feld.

Beispiel:
InputRoot.XML.Data.Invoice
Bei diesem Beispiel beginnt der Broker am Ausgangspunkt 'InputRoot' (die oberste Ebene der Eingabenachricht in einem Rechenknoten) und arbeitet sich dann durch die entsprechenden darunterliegenden Ebenen durch. Zuerst navigiert er vom Stammelement zum ersten untergeordneten Feld mit dem Namen 'XML' und dann zum ersten untergeordneten Feld des Feldes 'XML' mit dem Namen 'Data'. Schließlich navigiert der Broker zum ersten untergeordneten Feld des Feldes 'Data' mit dem Namen 'Invoice'. Bei Verwendung dieses Feldverweises in einem ESQL-Programm erfolgt immer ein Zugriff auf das Feld 'Invoice'.
Hierbei handelt es sich um die einfachste, bequemste und gängigste Form des Feldverweises. Es bestehen jedoch zwei Einschränkungen:
  • Bei den Namen, die verwendet werden, muss es sich um gültige ESQL-Kennungen handeln, daher können nur Namen verwendet werden, die den ESQL-Regeln entsprechen. Diese Namen können daher nur alphanumerische Zeichen und Unterstriche (_) enthalten, das erste Zeichen darf kein numerisches Zeichen sein, und die Namen müssen aus mindestens einem Zeichen bestehen. Sie können diese Einschränkungen umgehen, indem Sie Namen, die diesen Regeln nicht entsprechen, in Anführungszeichen setzen. Beispiel:
    InputRoot.XML."Customer Data".Invoice
    Bei Verweisen auf Felder, die doppelte Anführungszeichen enthalten, müssen Sie die Verweise in zwei doppelte Anführungszeichen setzen. Beispiel:
    Body.Message.""hello""

    Einige Bezeichner sind reservierte Schlüsselwörter, die Sie jedoch mit Ausnahme des Korrelationsnamens in Feldverweisen verwenden können, ohne sie in Anführungszeichen zu setzen.

  • Da die Namen der Felder im ESQL-Programm verwendet werden, müssen sie bei der Erstellung des Programms bereits bekannt sein. Sie kann mit Hilfe einer alternativen Syntax umgangen werden, die geschweifte Klammern ({ ... } ) verwendet. Mit Hilfe dieser Syntax können Sie beliebige Ausdrücke verwenden, die einen Wert ungleich Null des Typs CHARACTER zurückgeben.
    Beispiel:
    InputRoot.XML."Customer Data".{'Customer-' || 
    CurrentCustomer}.Invoice
    In diesem Fall befinden sich die Rechnungen in einem Ordner mit einem Namen, der durch Verknüpfung des Zeichenliterals 'Customer-' mit dem Wert in 'CurrentCustomer' (muss in diesem Beispiel eine deklarierte Variable des Typs 'Character' sein) gebildet wird.

In einem Pfadelement können Sie den Stern (*) als Platzhalterzeichen für einen beliebigen Namen verwenden. Sie können auch den Stern "*" für die Angabe eines Namensteils verwenden. Wenn Sie beispielsweise Präfix* angeben, steht dies für einen beliebigen Namen, der mit "Präfix" beginnt.

Beachten Sie, dass alles, was in ESQL in Anführungszeichen gesetzt wird, zu einem Bezeichner wird, und alles, was in einfache Anführungszeichen gesetzt wird, dadurch zu einem Zeichenliteral wird. Sie müssen alle Zeichenfolgen in einfache Anführungszeichen setzen.

Weitere Informationen hierzu finden Sie auch unter:
  • Namespaces mit einer Beschreibung der verschiedenen Kombinationen von Namespace und Name
  • Zielfeldverweise mit einer Beschreibung der verschiedenen Kombinationen von Feldverweisen
  • Indizes mit einer Beschreibung der verschiedenen Kombinationen von Indexklauseln
  • Typen mit einer Beschreibung der verschiedenen Kombinationen von Typen

Namespaces

Feldnamen können zu Namespaces gehören. Feldverweise unterstützen Namespaces auf folgende Weise:
  • Jedes Feld in jedem Feldverweis, der eine Namensklausel enthält, kann auch eine Namespace-Klausel enthalten, die den Namespace definiert, zu dem der angegebene Name gehört.
  • Jeder Namespace kann über eine einfache ID oder über einen in geschweifte Klammern gesetzten Ausdruck definiert werden. Wenn es sich bei einer ID um den Namen einer deklarierten Namespaceskonstanten handelt, wird der Wert der Konstanten verwendet. Wenn ein Ausdruck verwendet wird, muss dieser einen Nicht-Null-Wert des Typs CHARACTER zurückgeben.
  • Die Namespace-Klausel * gibt explizit an, dass Namespace-Informationen bei der Lokalisierung von Feldern in einer Baumstruktur ignoriert werden.
  • Eine Namenbereichsklause ohne ID, Ausdruck oder *, d. h. nur mit der Angabe von :, gibt explizit den Nicht-Ziel-Namespace an.

Indizes

Jedes Feld eines Feldverweises kann eine Indexklausel enthalten. Diese Klausel ist durch eckige Klammern ( [ ... ] ) gekennzeichnet und akzeptiert alle Ausdrücke, die einen Nicht-Null-Wert des Typs INTEGER zurückgeben. Mit dieser Klausel wird festgelegt, welches von mehreren Feldern mit demselben Namen ausgewählt werden soll. Vom ersten Feld an sind alle Felder nummeriert. Die Nummerierung beginnt bei eins. Wenn diese Klausel nicht vorhanden ist, wird davon ausgegangen, dass das erste Feld erforderlich ist. Folglich haben die zwei folgenden Beispiele dieselbe Bedeutung.
InputRoot.XML.Data[1].Invoice
InputRoot.XML.Data.Invoice[1] 
Dieses Konstrukt wird häufig mit einer Indexvariablen verwendet, so dass eine Schleife all diese Felder in Folge abarbeitet. Beispiel:
WHILE count < 32 DO
SET TOTAL = TOTAL + InputRoot.XML.Data.Invoice[count].Amount;
SET COUNT = COUNT + 1 
END WHILE;
Allerdings muss dieses Konstrukt mit Vorsicht eingesetzt werden, da hier davon ausgegangen wird, dass der Broker in der Schleife jedes Mal wieder von vorne beginnen muss. Das heißt, je größer der Wiederholungszähler, desto schlechter die Leistung. In diesen Fällen ist es besser, eine Feldverweisvariable zu verwenden.
Indexausdrücken kann optional ein Kleiner-als-Zeichen ( "<" ) vorangestellt werden. Dieses gibt an, dass das gewünschte Feld indexiert werden soll, ausgehend vom letzten Feld. In diesem Fall verweist Index 1 auf das letzte Feld und Index 2 auf das vorletzte Feld. Ebenso kann ein Größer-als-Zeichen verwendet werden, wenn vom ersten Feld an gezählt werden soll. Im folgenden Beispiel werden vom ESQL-Code Indizes mit vier Feldern des Namens 'Invoice' verarbeitet:
InputRoot.XML.Data.Invoice       -- Das erste Feld wird ausgewählt
InputRoot.XML.Data.Invoice[1]    -- Das erste Feld wird ausgewählt
InputRoot.XML.Data.Invoice[>] -- Das erste Feld wird ausgewählt
InputRoot.XML.Data.Invoice[>1] -- Das erste Feld wird ausgewählt
InputRoot.XML.Data.Invoice[>2] -- Das zweite Feld wird ausgewählt
InputRoot.XML.Data.Invoice[<]    -- Das vierte Feld wird ausgewählt
InputRoot.XML.Data.Invoice[<1]   -- Das vierte Feld wird ausgewählt
InputRoot.XML.Data.Invoice[<2]   -- Das dritte Feld wird ausgewählt
InputRoot.XML.Data.Invoice[<3]   -- Das zweite Feld wird ausgewählt
Eine Indexklausel kann auch aus einem leeren Paar eckiger Klammern ( "[ ]" ) bestehen. Dies gibt an, dass alle Felder des entsprechenden Namens ausgewählt werden sollen. Verwenden Sie dieses Konstrukt mit Funktionen und Anweisungen, die Listen erwarten (z. B. die Funktionen SELECT, CARDINALITY, SINGULAR und EXISTS oder die SET-Anweisung) .

Typen

Jedes Feld eines Feldverweises kann eine Typklausel enthalten. Diese Typklauseln sind durch runde Klammern ( "( )" ) gekennzeichnet und gestatten die Verwendung beliebiger Ausdrücke, die einen Wert ungleich null des Typs INTEGER zurückgeben. Durch die Angabe eines Typausdrucks wird die Auswahl der Felder auf solche desselben Typs beschränkt. Dieses Konstrukt wird am häufigsten in Verbindung mit generischen XML-Formaten verwendet, die viele Feldtypen enthalten und in denen ein einziges XML-Feld sowohl Attribute als auch weitere XML-Felder mit demselben Namen enthalten kann.

Beispiel:
<Item Value = '1234' >
<Value>5678</Value>
</Item>

Hier verfügt das XML-Feld "Element" über zwei untergeordnete Felder, beide mit dem Namen "Value" (Wert). Das untergeordnete Feld kann mittels zweier Typklauseln unterschieden werden: Element.(<Domäne>.Attribut)Wert zur Auswahl des Attributs und Element.(XML.Element)Werte zur Auswahl des Feldes. Dabei ist die <Domäne> entweder XML, XMLNS oder XMLNSC, wie von der Nachrichtendomäne der Quelle festgelegt.

TYPEINSCHRäNKUNGEN

EINE TYPEINSCHRäNKUNG üBERPRüFT DEN VON EINEM FELDVERWEIS ZURüCKGEGEBENEN DATENTYP.
Anmerkungen:
  1. Bei NameSkalarerDatentyp kann es sich um BOOLEAN, INTEGER, INT, FLOAT, DECIMAL, DEC, DATE, TIME, TIMESTAMP, GMTTIME, GMTTIMESTAMP, INTERVAL, CHARACTER, CHAR, BLOB, BIT handeln.

Normalerweise bewirkt eine Typeinschränkung, dass der skalare Wert der Referenz extrahiert (wie bei der FIELDVALUE-Funktion) und eine Ausnahme ausgelöst wird, wenn die Referenz den falschen Typ hat. Laut Definition wird eine Ausnahme für alle nicht vorhandenen Felder ausgelöst, da diese den Wert NULL ergeben. Auf diese Weise lassen sich Ausnahmen schnell und einfach auslösen, wenn in Nachrichten wichtige Felder fehlen.

Wenn jedoch Typeinschränkungen in Ausdrücken auftreten, die an eine Datenbank übermittelt werden sollen (wenn sie z. B. in einer WHERE-Klausel sind), wird mit Hilfe der Informationen bestimmt, ob der Ausdruck an die Datenbank übergeben werden kann. Dies kann dann von Bedeutung sein, wenn eine WHERE-Klausel einen UMSETZUNGSAUSDRUCK enthält, der in einer Datenbanktabellenspalte aktiv ist. Ohne Typeinschränkung können solche Ausdrücke nicht an die Datenbank übergeben werden, da der Broker nicht weiß, ob die Datenbank die erforderliche Konvertierung ausführen kann. Seien Sie bei der Verwendung von Umsetzungsausdrücken in Spaltenwerten stets besonders sorgfältig, da einige Datenbanken äußerst begrenzte Konvertierungsfunktionen haben.

Zusammenfassung

*, *[..], (..)*, (..)*[..]
In keinem dieser Formate wird ein Name oder Namespace angegeben. Das Zielfeld kann einen beliebigen Namen in einem beliebigen Namespace oder in keinem Namespace haben. Das Zielfeld wird ausschließlich, soweit erforderlich, nach Typ, Index oder Typ und Index lokalisiert.
Namens-ID, Namens-ID[..], (..)Namens-ID, (..)Namens-ID[..]
In all diesen Formaten wird ein Name, jedoch kein Namespace angegeben. Das Zielfeld wird durch Namespace und Name und gegebenenfalls auch durch Typ und Index lokalisiert.

Es wird davon ausgegangen, dass der Namespace der einzige Namespace im Namespacespfad mit diesem Namen ist. Der einzige Namespace, der im Pfad enthalten sein kann, ist der Namespace 'notarget'.

Diese Art von Referenz gab es bereits vor der Einführung von Namespaces. Zwar hat sich ihr Verhalten dahingehend geändert, dass jetzt sowohl Name als auch Namespace verglichen werden. Dies sollte jedoch keine Auswirkung auf das Verhalten vorhandener Umwandlungen haben, weil alle vorhandenen Umwandlungen ihre Felder im Namespace 'notarget' erstellen.

: *, :*[..], (..):*, (..):*[..]
In diesen Formaten wird der Nicht-Ziel-Namespace, jedoch kein Name angegeben. Das Zielfeld wird durch seinen Namespace und gegebenenfalls auch durch Typ und Index lokalisiert.
: Namens-ID, :Namens-ID[..], (..):Namens-ID, (..):Namens-ID[..]
Alle oben genannten Formate geben einen Namen und den Nicht-Ziel-Namespace an. Das Zielfeld wird durch Namespace und Name und gegebenenfalls auch durch Typ und Index lokalisiert.
* :*, *:*[..], (..)*:*, (..)*:*[..]
In keinem dieser Formate wird ein Name oder Namespace angegeben. Hinweis: "*:*" ist äquivalent zu "*" und entspricht keinem Namespace sowie einem beliebigen Namespace. Das Zielfeld kann einen beliebigen Namen in einem beliebigen Namespace oder in keinem Namespace haben. Das Zielfeld wird ausschließlich, soweit erforderlich, nach Typ, Index oder Typ und Index lokalisiert.
* :Namens-ID, *:Namens-ID[..], (..)*:Namens-ID, (..)*:Namens-ID[..]
In all diesen Formaten wird ein Name, jedoch kein Namespace angegeben. Das Zielfeld wird durch den Namen und gegebenenfalls auch durch Typ und Index lokalisiert.
Bereichs-ID :*, Bereichs-ID:*[..], (..)Bereichs-ID:*, (..)Bereichs-ID:*[..]
In all diesen Formaten wird ein Namespace, jedoch kein Name angegeben. Das Zielfeld wird durch den Namespace und gegebenenfalls auch durch Typ und Index lokalisiert.
Bereichs-ID :Namens-ID, Bereichs-ID:Namens-ID[..], (..)Bereichs-ID:Namens-ID, (..)Bereichs-ID:Namens-ID[..]
In all diesen Formaten wird ein Namespace und ein Name angegeben. Das Zielfeld wird durch Namespace und Name und gegebenenfalls auch durch Typ und Index lokalisiert.

In allen vorherigen Fällen entspricht ein Name oder ein Namespace, der über einen in geschweiften Klammern ({}) gesetzten Ausdruck angegeben wurde, einem als ID angegebenen Namen.

Der Definition nach entspricht der Name des Nicht-Ziel-Namespaces einer leeren Zeichenfolge. Die leere Zeichenfolge kann über Ausdrücke ausgewählt werden, die eine leere Zeichenfolge ergeben, über die leere ID "" oder über einen Verweis auf eine Namespaceskonstante, die als leere Zeichenfolge definiert wurde.

Zielfeldverweise

Die Verwendung von Feldverweisen beinhaltet in der Regel die Suche nach einem vorhandenen Feld. Falls das benötigte Feld jedoch nicht existiert, wie normalerweise im Falle von Feldverweisen, die Ziele von SET-Anweisungen sind, und von Feldverweisen in den AS-Klauseln von SELECT-Funktionen, wird es erstellt.

In diesen Situationen gibt es verschiedene Umstände, in denen der Broker den benötigten Namen oder Namespace nicht liefern kann. Dann gelten die folgenden allgemeinen Grundregeln:
  • Wenn die Namensklausel nicht vorhanden ist bzw. keinen Namen angibt, und die Namespace-Klausel nicht vorhanden ist oder keinen Namespace angibt bzw. impliziert (d. h. es ist kein Name oder Namespace verfügbar), gilt Folgendes:
    • Wenn der Zuordnungsalgorithmus nicht den Namen aus einem vorhandenen Feld kopiert, werden sowohl als Name als auch als Namespace für das neue Feld die leere Zeichenfolge festgelegt, und das Namenskennzeichen wird nicht automatisch gesetzt.

      Ist keine Typspezifikation angegeben, lautet der Typ des Feldes nicht Name oder NameValue, was im Endeffekt bedeutet, dass das neue Feld keinen Namen hat

      .
    • Andernfalls, wenn der Zuordnungsalgorithmus den Namen aus einem vorhandenen Feld kopiert, werden sowohl der Name als auch der Namespace für das neue Feld aus dem vorhandenen Feld kopiert, und das Kennzeichen Name wird automatisch gesetzt.
  • Wenn die Namensklausel vorhanden ist und einen Namen angibt, aber die Namespace-Klausel nicht vorhanden ist oder keinen Namespace angibt oder impliziert (d. h., es ist ein Name verfügbar, aber kein Namespace), gilt für das neue Feld Folgendes:
    • Name wird auf den angegebenen Wert gesetzt
    • Namespace wird auf die leere Zeichenfolge gesetzt
    • Die Kennzeichnung Name wird automatisch gesetzt
  • Wenn die Namensklausel nicht vorhanden ist oder keinen Namen angibt, aber die Namespace-Klausel vorhanden ist und einen Namespace angibt oder impliziert (d. h., es ist ein Namespace verfügbar, aber kein Name), gilt für das neue Feld Folgendes:
    • Namespace wird auf den angegebenen Wert gesetzt
    • Name wird auf die leere Zeichenfolge gesetzt
    • Die Kennzeichnung Name wird automatisch gesetzt
  • Wenn die Namensklausel vorhanden ist und einen Namen angibt und wenn die Namespace-Klausel vorhanden ist und einen Namespace angibt oder impliziert, gilt für das neue Feld Folgendes:
    • Name wird auf den angegebenen Wert gesetzt
    • Namespace wird auf den angegebenen Wert gesetzt
    • Die Kennzeichnung Name wird automatisch gesetzt
Es gibt auch Fälle, in denen der Broker Felder zusätzlich zu denen, auf die durch Feldverweise verwiesen wird, erstellt:
  • Baumstrukturkopie: Neue Felder werden von einem Algorithmus erstellt, der eine Quellenbaumstruktur als Vorlage verwendet. Beim Kopieren des Namens eines Quellenfeldes in ein neues Feld wird auch der Namespace des Quellenfeldes kopiert.
  • Anonyme Auswahlausdrücke: AS-Klauseln sind in SELECT-Klauseln nicht obligatorisch. Sind keine enthalten, werden die Namen für die neu erstellten Felder auf Standardwerte gesetzt (siehe Funktion SELECT).

    Diese Standardwerte können von Feldnamen oder Spaltennamen abgeleitet werden oder können einfach nur systemgenerierte Folgenamen sein. Ist der Name ein Feldname, handelt es sich im Endeffekt um eine Baumstrukturkopie, und der Namespacesname wird wie oben beschrieben kopiert.

    Andernfalls wird der Namespace des neu erstellten Feldes abgeleitet, indem der Pfad durchsucht wird, d. h., der Name wird wie die NameId-Syntax eines Feldverweises behandelt.

Auswirkung der Einstellung eines Feldes auf NULL

Seien Sie vorsichtig, wenn Sie einem Feld einen NULL-Wert zuweisen. Der folgende Befehl beispielsweise löscht das Feld Name:
SET OutputRoot.XML.Msg.Data.Name = NULL;  -- dieser Befehl löscht das Feld
So weisen Sie einem Feld einen NULL-Wert korrekt zu:
SET OutputRoot.XML.Msg.Data.Name VALUE = NULL;  
-- dieser Befehl weist einem Feld einen NULL-Wert zu, ohne es zu löschen
Anmerkung: Für Benutzer bezüglich Abwärtskompatibilität

Aus Gründen der Abwärtskompatibilität wird das Schlüsselwort LAST nach wie vor unterstützt, die Verwendung ist jedoch veraltet. LAST kann nicht als Teil eines Indexausdrucks verwendet werden: [LAST] ist gültig und entspricht [<], [LAST3] ist jedoch ungültig.

Das Schlüsselwort LAST wurde durch folgende Pfeilsyntax ersetzt, die die Angabe einer Suchrichtung und eines Index ermöglicht:
Field [ > ] -- Das erste Feld, äquivalent zu [ 1 ]0
Field [ > (a + b) * 2 ]
Field [ < ]                   -- Das letzte Feld, äquivalent zu [ LAST ]
Field [ < 1 ]	                -- Das letzte Feld, äquivalent zu [ LAST ]
Field [ < 2 ]	                -- Das vorletzte Feld
Field [ < (a + b) / 3 ]
Zugehörige Konzepte
Übersicht zu ESQL
Bemerkungen | Marken | Downloads | Bibliothek | Unterstützung | Rückmeldung
Copyright IBM Corporation 1999, 2006 Letzte Aktualisierung: 18.05.2006
ak04861_