CREATE PROCEDURE-Anweisung

Die Anweisungen CREATE FUNCTION und CREATE PROCEDURE definieren eine aufrufbare Funktion oder Prozedur, die in der Regel als "Routine" bezeichnet wird.

SYNTAX

Anmerkungen:
  1. Hat die Routine den Typ FUNCTION (Funktion), ist der Richtungsanzeiger (IN, OUT, INOUT) für jeden Parameter optional. Wir empfehlen jedoch dringend, aus Dokumentationsgründen einen Richtungsanzeiger für alle neuen Routinen mit beliebigem Typ festzulegen.
  2. Wenn die Klausel NAMESPACE oder NAME verwendet wird, ist ihr Wert implizit konstant und hat den Typ CHARACTER (Zeichen). Weitere Informationen zur Verwendung von CONSTANT-Variablen finden Sie im Abschnitt DECLARE-Anweisung.
  3. Hat die Routine den Typ FUNCTION, kann für LANGUAGE nicht DATABASE angegeben werden.

Übersicht

Die Anweisungen CREATE FUNCTION und CREATE PROCEDURE definieren eine aufrufbare Funktion oder Prozedur, die in der Regel als "Routine" bezeichnet wird.

Anmerkung: In früheren Produktversionen wurden die Anweisungen CREATE FUNCTION und CREATE PROCEDURE anders eingesetzt und hatten andere Funktionen. Sie sind mittlerweile jedoch weiterentwickelt worden, so dass es nur noch wenige Unterschiede gibt. Die Unterschiede zwischen Funktionen und Prozeduren sind unter 1 und 3 unterhalb des Syntaxdiagramms aufgelistet.

Routinen sind bei der Erstellung wiederverwendbarer Codeblöcke hilfreich, die unabhängig mehrere Male ausgeführt werden können. Sie lassen sich als Reihe von ESQL-Anweisungen, als Java-Methode oder als in einer Datenbank gespeicherte Prozedur implementieren. Diese Vielfalt der Implementierungsmöglichkeiten bedeutet, dass einige der Klauseln im Syntaxdiagramm nicht für alle Routinetypen zutreffen (oder nicht zulässig sind).

Jede Routine hat einen Namen, der innerhalb des Schemas, der die Routine angehört, eindeutig sein muss. Routinenamen können daher nicht überladen werden: wenn der Broker eine überladene Routine feststellt, gibt er eine Ausnahmebedingung aus.

Die LANGUAGE-Klausel gibt die Sprache an, in der der Hauptteil der Routine geschrieben wird. Folgende Optionen stehen zur Verfügung:
DATABASE
Die Prozedur wird als eine in einer Datenbank gespeicherte Prozedur aufgerufen.
ESQL
Die Prozedur wird als eine ESQL-Routine aufgerufen.
JAVA
Die Prozedur wird als eine statische Methode in einer Java-Klasse aufgerufen.
Nicht angegeben
Wenn Sie die LANGUAGE-Klausel nicht angeben, wird als Standardsprache ESQL verwendet, es sei denn, Sie geben die Klausel EXTERNAL NAME an. In diesem Fall wird als Standardsprache DATABASE verwendet.
Die Verwendung der LANGUAGE-Klausel unterliegt Einschränkungen. Folgendes darf nicht verwendet werden:
  • Die ESQL-Option mit einer EXTERNAL NAME-Klausel
  • Die Optionen DATABASE oder JAVA ohne eine EXTERNAL NAME-Klausel
  • Die DATABASE-Option mit dem Routinetyp FUNCTION

Geben Sie den Namen der Routine mit der Klausel Routinename und die Parameter der Routine mit der Klausel Parameterliste an. Wenn die LANGUAGE-Klausel ESQL angibt, muss die Routine unter Verwendung einer einzelnen ESQL-Anweisung implementiert werden. Diese Anweisung ist sehr nützlich, wenn es sich um eine Verbindungsanweisung handelt (BEGIN ... END), da sie dann so viele ESQL-Anweisungen enthalten kann, wie zur Ausübung ihrer Funktionen erforderlich sind.

Alternativ können Sie in der LANGUAGE-Klausel eine andere Sprache als ESQL angeben, anstatt einen ESQL-Hauptteil für die Routine bereitzustellen. Auf diese Weise sind Sie in der Lage, mit der EXTERNAL NAME-Klausel auf den tatsächlichen Hauptteil der Routine zu verweisen, wenn er extern zum Broker lokalisiert ist. Weitere Informationen zur Verwendung der EXTERNAL NAME-Klausel finden Sie unter Gespeicherte Prozeduren aufrufen und Eine Java-Routine aufrufen.

Routinen mit beliebigem LANGUAGE-Typ können die Parameter IN, OUT und INOUT haben. Auf diese Weise kann der Aufrufende mehrere Werte in die Routine einstellen sowie mehrere aktualisierte Werte zurückempfangen. Dies ist ergänzend zu möglichen RETURNS-Klauseln, die die Routine haben kann. Die RETURNS-Klausel ermöglicht der Routine, einen Wert an den Aufrufenden zurückzuleiten.

Routinen, die in verschiedenen Sprachen implementiert sind, haben ihre eigenen Einschränkungen dahingehend, welche Datentypen eingestellt oder zurückgegeben werden können. Sie sind nachfolgend dokumentiert. Der Datentyp des zurückgegebenen Wertes muss dem Datentyp des Wertes entsprechen, der laut Definition von der Routine zurückgegeben werden soll. Wenn eine Routine laut Definition einen Rückgabewert haben soll, kann ihn der Aufrufende der Routine nicht ignorieren. Ausführliche Informationen finden Sie in der CALL-Anweisung.

Routinen lassen sich in einem Modul oder in einem Schema definieren. In einem Modul definierte Routinen liegen im lokalen Bereich des aktuellen Knotens, d. h. sie können nur von Code aufgerufen werden, der demselben Modul (oder Knoten) angehört. Routinen, die in Schemabereichen definiert sind, können jedoch von einem der folgenden Codes aufgerufen werden:
  • Code in demselben Schema.
  • Code in einem anderen Schema, wenn eines der folgenden Szenarios gilt:
    1. Die PATH-Klausel des anderen Schemas enthält den Pfad zur aufgerufenen Routine oder
    2. Die aufgerufene Routine wird unter Verwendung ihres vollständig qualifizierten Namens (bestehend aus ihrem Namen, dem ihr Schemaname - getrennt durch einen Punkt - vorangestellt ist).
Wenn Sie also dieselbe Routine in mehreren Knoten aufrufen möchten, definieren Sie sie in einem Schema.

Bezüglich der Sprache oder des Routinetyps muss die Methode des Aufrufens der Routine der Methode ihrer Deklaration entsprechen. Wenn die Routine eine RETURNS-Klausel besitzt, verwenden Sie entweder die Aufrufsyntax FUNCTION oder eine CALL-Anweisung mit einer INTO-Klausel. Umgekehrt gilt: Hat eine Routine keine RETURNS-Klausel, müssen Sie eine CALL-Anweisung ohne INTO-Klausel verwenden.

Parameterrichtungen

Routinen, die an Parameter übermittelt werden, ist auch stets eine Richtung zugeordnet. Möglich sind jeweils:
IN
Der Wert des Parameters kann nicht von der Routine geändert werden. Ein NULL-Wert für den Parameter ist zulässig und kann an die Routine übermittelt werden.
OUT
Wenn er von der aufgerufenen Routine empfangen wird, hat der in die Routine eingestellte Parameter immer den Wert NULL als korrekten Datentyp. Dies geschieht unabhängig davon, welchen Wert er vor Aufruf der Routine hatte. Die Routine darf den Wert des Parameters ändern.
INOUT
INOUT ist sowohl ein IN-Parameter als auch ein OUT-Parameter. Er stellt einen Wert in die Routine, der dann von ihr geändert werden kann. Ein NULL-Wert für den Parameter ist zulässig und kann sowohl in die Routine eingestellt als auch aus ihr heraus übermittelt werden.

Hat die Routine den Typ FUNCTION (Funktion), ist der Richtungsanzeiger (IN, OUT, INOUT) für jeden Parameter optional. Wir empfehlen jedoch dringend, aus Dokumentationsgründen einen Richtungsanzeiger für alle neuen Routinen mit beliebigem Typ festzulegen.

ESQL-Variablen, die als CONSTANT deklariert sind (oder Verweise auf als CONSTANT deklarierte Variablen) dürfen nicht die Richtung OUT oder INOUT haben.

ESQL-Routinen

ESQL-Routinen sind in ESQL geschrieben, und ihre LANGUAGE-Klausel gibt die Sprache ESQL an. Als Hauptteil einer ESQL-Routine wird für gewöhnlich eine Verbindungsanweisung in der Form von BEGIN … END verwendet, die mehrere Anweisungen zur Verarbeitung der Parameter enthält, die an die Routine übermittelt wurden.

ESQL-Beispiel 1

Im nachfolgenden Beispiel wird dieselbe Prozedur wie in Beispiel 1 einer Datenbankroutine angezeigt, allerdings als ESQL-Routine und nicht als eine gespeicherte Prozedur implementiert. Die CALL-Syntax und Ergebnisse dieser Routine sind mit denen in Einschränkungen bei Java-Routinen identisch.
CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  OUT parm2  CHARACTER,
  INOUT parm3 CHARACTER )
BEGIN   
   SET parm2 = parm3;
   SET parm3 = parm1;
              END;

ESQL-Beispiel 2

Diese Beispielprozedur zeigt die rekursive Verwendung einer ESQL-Routine. Sie analysiert die Syntax einer Baumstruktur an sämtlichen Stellen am und unterhalb des angegebenen Ausgangspunkts und dokumentiert anschließend das Ergebnis:

SET OutputRoot.MQMD = InputRoot.MQMD;

  DECLARE answer CHARACTER;
  SET     answer = '';

  CALL navigate(InputRoot.XML, answer);
  SET OutputRoot.XML.Data.FieldNames = answer;


  CREATE PROCEDURE navigate (IN root REFERENCE, INOUT answer CHARACTER)
  BEGIN   
    SET answer = answer || 'Reached Field... Type:' || CAST(FIELDTYPE(root) AS CHAR)||
': Name:' || FIELDNAME(root) || ': Value :' || root || ': ';

    DECLARE cursor REFERENCE TO root;
    MOVE cursor FIRSTCHILD;
    IF LASTMOVE(cursor) THEN
      SET answer = answer || 'Field has children... drilling down ';
             ELSE
      SET answer = answer || 'Listing siblings... ';
    END IF;   

    WHILE LASTMOVE(cursor) DO
      CALL navigate(cursor, answer);
      MOVE cursor NEXTSIBLING;
    END WHILE;
    SET answer = answer || 'Finished siblings... Popping up ';
  END;

Lautet die Eingabenachricht wie folgt:

<Person>
  <Name>John Smith</Name>
  <Salary period='monthly' taxable='yes'>-1200</Salary>
</Person>

dann erstellt die Prozedur die folgende Ausgabe, die manuell formatiert wurde:

  Reached Field... Type:16777232: Name:XML: Value :: Field has children... drilling down 
Reached Field... Type:16777216: Name:Person: Value :: Field has children... drilling down 
Reached Field... Type:16777216: Name:Name: 
  Value :John Smith: Field has children... drilling down 
  Reached Field... Type:33554432: Name:: 
  Value :John Smith: Listing siblings... Finished siblings... Popping up
  Finished siblings... Popping up 
  Reached Field... Type:16777216: Name:Salary:
  Value :-1200: Field has children... drilling down 
  Reached Field... Type:50331648: Name:period: 
  Value :monthly: Listing siblings... Finished siblings... Popping up
  Reached Field... Type:50331648: Name:taxable: 
  Value :yes: Listing siblings... Finished siblings... Popping up 
  Reached Field... Type:33554432: Name:: 
  Value :-1200: Listing siblings... Finished siblings... Popping up 
  Finished siblings... Popping up 
  Finished siblings... Popping up 
  Finished siblings... Popping up

Java-Routinen

Eine Java-Routine ist als Java-Methode implementiert und hat die LANGUAGE-Klausel JAVA. Bei Java-Routinen muss der ExterneRoutineName den Klassennamen und den Namen der Java-Methode enthalten, die aufgerufen wird. Geben Sie den ExterneRoutineName wie folgt an:
 >>--"-- Klassenname---.---Methodenname--"--------------><
Dabei steht Klassenname für die Klasse, die die Methode enthält, und Methodenname gibt die Methode an, die aufgerufen werden soll. Wenn die Klasse Teil eines Pakets ist, muss der Teil mit der Klassen-ID das komplette Paketpräfix einschließen, z. B. "com.ibm.broker.test.MyClass.myMethod".

Um nach der Java-Klasse zu suchen, geht der Broker wie im Abschnitt Implementierung von Java-Klassen beschrieben vor.

Jede Java-Methode, die Sie aufrufen möchten, muss die folgende Basissignatur haben:
public static <Rückgabetyp> <Methodenname> (< 0 - N Parameter>)

Dabei muss der <Rückgabetyp> in der Liste der Java-Datentypen IN aus der Tabelle in der Zuordnung von ESQL zum Java-Datentyp stammen (ausgenommen REFERENCE, da dieser Typ als Rückgabewert unzulässig ist) oder dem Java-Datentyp 'void' entsprechen. Die Parameterdatentypen müssen ebenfalls aus der Tabelle der Zuordnung von ESQL zum Java-Datentyp stammen. Zudem darf die Java-Methode keine exception throws-Klausel (Ausnahmeauslöser) in ihrer Signatur haben.

Die Signatur der Java-Methode muss der ESQL-Routinedeklaration der Methode entsprechen. Des Weiteren müssen Sie folgende Regeln beachten:
  • Stellen Sie sicher, dass der Name der Java-Methode einschließlich des Klassennamens sowie der Paketqualifikationsmerkmale dem externen Namen (EXTERNAL NAME) der Prozedur entspricht.
  • Ist der Java-Rückgabetyp typenlos, sollten Sie keine RETURNS-Klausel in die Definition der ESQL-Routine stellen. Ist der Java-Rückgabetyp jedoch nicht typenlos, müssen Sie eine RETURNS-Klausel in die Definition der ESQL-Routine stellen.
  • Stellen Sie sicher, dass alle Parametertypen und -richtungen gemäß den in der Tabelle in der Zuordnung von ESQL zum Java-Datentyp aufgelisteten Regeln der ESQL-Deklaration entsprechen.
  • Stellen Sie sicher, dass der Rückgabetyp der Methode dem Datentyp der RETURNS-Klausel entspricht.
  • Stellen Sie den EXTERNAL NAME (externen Namen) in Anführungszeichen, da er mindestens "class.method" (Klasse.Methode) enthalten muss.
  • Wenn Sie eine überlastete Java-Methode aufrufen möchten, müssen Sie eine separate ESQL-Definition für jede überlastete Methode erstellen und jeder ESQL-Definition einen eindeutigen Routinenamen geben.

Sie können in Ihrer Java-Methode die API des benutzerdefinierten Java-Knotens verwenden, wenn Sie die in Einschränkungen bei Java-Routinen aufgeführten Einschränkungen beachten. Weitere Informationen zur Verwendung der API des benutzerdefinierten Knotens finden Sie unter Benutzerdefinierten Java-Knoten kompilieren.

Beispiel 1 einer Java-Routine

Diese Routine enthält drei Parameter unterschiedlicher Richtungen und gibt eine Ganzzahl zurück, die dem Java-Rückgabetyp java.lang.Long entspricht.

CREATE FUNCTION  myProc1( IN P1 INTEGER, OUT P2 INTEGER, INOUT P3 INTEGER )
 RETURNS INTEGER
 LANGUAGE JAVA 
 EXTERNAL NAME "com.ibm.broker.test.MyClass.myMethod1";

Sie können für den Aufruf von myProc1 folgenden ESQL-Ausdruck verwenden:

CALL myProc1( intVar1, intVar2, intVar3) INTO intReturnVar3;
-- oder
SET intReturnVar3 = myProc1( intVar1, intVar2, intVar3);

Beispiel 2 einer Java-Routine

Diese Routine enthält drei Parameter unterschiedlicher Richtungen und hat den Java-Rückgabetyp void (typenlos).

CREATE PROCEDURE myProc2( IN P1 INTEGER, OUT P2 INTEGER, INOUT P3 INTEGER )
 LANGUAGE JAVA 
 nEXTERNAL NAME "com.ibm.broker.test.MyClass.myMethod2";

Sie müssen für den Aufruf von myProc2 folgenden ESQL-Ausdruck verwenden:

CALL myProc2(intVar1, intVar2, intVar3);

Die folgende Java-Klasse bietet eine Methode für jedes der Java-Beispiele:

package com.ibm.broker.test;

class MyClass {
public static Long myMethod1( Long P1, Long[] P2 Long[] P3) { ... }
public static void myMethod2( Long P2, Long[] P2 Long[] P3) { ... }

 /*  Wenn eine dieser Methoden aufgerufen wird:
    P1 kann den Wert NULL haben oder nicht (abhängig vom Wert von intVar1).
    P2[0] hat stets den Wert NULL (unabhängig vom Wert von intVar2).
    P3[0] kann den Wert NULL haben oder nicht (abhängig vom Wert von intVar3).
    Alles entspricht der Verwendung von LANGUAGE ESQL-Routinen.
    Wenn diese Methoden Werte zurückgeben:
         intVar1 ist unverändert
         intVar2 kann immer noch den Wert NULL oder einen anderen Wert haben
         intVar3 kann denselben Wert oder einen anderen Wert haben
     Alles entspricht der Verwendung von LANGUAGE ESQL-Routinen.
     
    Wenn myMethod1 Folgendes zurückgibt: intReturnVar3 ist entweder NULL (wenn die
    Methode NULL zurückgibt) oder enthält den Wert, den die
    Methode zurückgegeben hat.
 */
}

Zuordnung von ESQL zum Java-Datentyp

In der folgenden Tabelle wird die Zuordnung von ESQL zu Java zusammengefasst.
Anmerkungen:
  • Nur die Java-Skalarwrapper werden an Java übergeben.
  • Die ESQL-Skalartypen werden Java-Datentypen als Objektwrapper oder Objektwrappergruppen zugeordnet, abhängig von der Richtung des Prozedurparameters. Jeder Wrapperbereich enthält genau ein Element.
  • Durch die Verwendung von Skalarobjektwrappern können NULL-Werte an Java-Methoden übermittelt und von dort abgerufen werden.
ESQL-Datentypen 1 Java IN-Datentypen Java INOUT- und OUT-Datentypen
INTEGER, INT java.lang.Long java.lang.Long []
FLOAT java.lang.Double java.lang.Double[]
DECIMAL java.math.BigDecimal java.math.BigDecimal[]
CHARACTER, CHAR java.lang.String java.lang.String[]
BLOB byte[] byte[][]
BIT java.util.BitSet java.util.BitSet[]
DATE com.ibm.broker.plugin.MbDate com.ibm.broker.plugin.MbDate[]
TIME 2 com.ibm.broker.plugin.MbTime com.ibm.broker.plugin.MbTime[]
GMTTIME 2 com.ibm.broker.plugin.MbTime com.ibm.broker.plugin.MbTime[]
TIMESTAMP 2 com.ibm.broker.plugin.MbTimestamp com.ibm.broker.plugin.MbTimestamp[]
GMTTIMESTAMP 2 com.ibm.broker.plugin.MbTimestamp com.ibm.broker.plugin.MbTimestamp[]
INTERVAL Wird nicht unterstützt Wird nicht unterstützt
BOOLEAN java.lang.Boolean java.lang.Boolean[]
REFERENCE (auf eine Nachrichtenbaumstruktur) 3 4 5 6 com.ibm.broker.plugin.MbElement com.ibm.broker.plugin.MbElement[] (Wird für INOUT unterstützt, nicht für OUT)
ROW Wird nicht unterstützt Wird nicht unterstützt
LIST Wird nicht unterstützt Wird nicht unterstützt
  1. Variablen, die als konstant deklariert werden (oder Referenzen auf Variablen, die als konstant deklariert werden), dürfen nicht die Richtung INOUT oder OUT aufweisen.
  2. Die in der Java-Variablen eingestellte Zeitzone ist nicht wichtig; Sie erhalten die erforderliche Zeitzone im ausgegebenen ESQL.
  3. Der Verweisparameter kann bei Übergabe an eine Java-Methode nicht den Wert NULL haben.
  4. Der Verweis kann bei Übergabe an eine Java-Methode nicht die Richtung OUT haben.
  5. Wenn ein MbElement von Java als INOUT-Parameter an ESQL zurückgegeben wird, muss es auf eine Position in derselben Nachrichtenbaumstruktur verweisen wie die, auf die das MbElement bei der Übergabe an die aufgerufene Java-Methode verwies.

    Wenn beispielsweise ein ESQL-Verweis auf OutputRoot.XML.Test als INOUT-MbElement an eine Java-Methode übergeben wird, bei Rückkehr des Aufrufs aber ein anderes MbElement an ESQL zurückgegeben wird, muss dieses andere Element ebenfalls auf eine Position innerhalb der OutputRoot-Baumstruktur verweisen.

  6. Ein MbElement kann nicht mit der RETURNS-Klausel an eine Java-Methode zurückgegeben werden, da dieser Verweis von einer ESQL-Routine nicht zurückgegeben werden kann. Dagegen kann ein MbElement (unter Berücksichtigung der oben unter 5 aufgeführten Bedingungen) als INOUT-Richtungsparameter zurückgegeben werden.

Ein Verweis auf eine Skalarvariable kann im Aufruf einer Java-Methode verwendet wurde, vorausgesetzt, der Datentyp der Variablen, auf die verwiesen wird, entspricht dem entsprechenden Datentyp in der Java-Programmsignatur.

Einschränkungen bei Java-Routinen

Für Java-Routinen, die in ESQL aufgerufen werden, gelten folgende Einschränkungen:
  • Stellen Sie sicher, dass die Java-Methode threadsicher ist (simultan verwendbar).
  • Es sind nur JDBC-Datenbankverbindungen des Typs 4 zulässig. Zudem sind Datenbankoperationen nicht Teil einer Brokertransaktion, d. h., sie sind nicht durch einen externen Ressourcenkoordinator steuerbar (wie es in einer XA-Umgebung der Fall wäre).
  • Die API des benutzerdefinierten Java-Knotens darf nur von dem Thread verwendet werden, der die Java-Methode aufgerufen hat.

    Es ist zulässig, Threads innerhalb Ihrer Methode zu starten. Einmal gestartete Threads dürfen jedoch keine Java-Plug-in-APIs verwenden und müssen die Steuerung wieder an den Broker zurückgeben.

    Beachten Sie, dass alle Einschränkungen hinsichtlich der Verwendung der API des benutzerdefinierten Knotens auch für Java-Methoden gelten, die aus ESQL aufgerufen werden.

  • Aus ESQL aufgerufene Java-Methoden dürfen die MbNode-Klasse nicht verwenden. Sie können also keine Objekte des Typs MbNode erstellen oder Methoden für ein vorhandenes MbNode-Objekt aufrufen.
  • Wenn Sie MQ- oder JMS-Aufgaben in einer Java-Methode ausführen möchten, die aus ESQL aufgerufen wurde, müssen Sie die Richtlinien für benutzerdefinierte Knoten zur Ausführung von MQ- und JMS-Aufgaben in einem benutzerdefinierten Knoten befolgen.

Implementierung von Java-Klassen

Es wird empfohlen, die Java-Klassen innerhalb eines Java-Archivs (JAR-Datei) einzusetzen. Es gibt zwei Methoden, um eine JAR-Datei im Broker einzusetzen:
  1. Durch Hinzufügen der Datei zu einer BAR-Datei

    Die JAR-Datei wird am effizientesten und flexibelsten im Broker implementiert, wenn Sie sie der BAR-Datei hinzufügen.

    Sie können die JAR-Datei manuell oder automatisch unter Verwendung der Tools zur BAR-Datei hinzufügen. Mit Hilfe der Tools lässt sich die JAR-Datei der BAR-Datei am einfachsten hinzufügen.

    Wenn die Tools die korrekte Java-Klasse in einem geöffneten Java-Projekt im Arbeitsbereich finden, wird die Java-Klasse automatisch in eine JAR-Datei kompiliert und zur BAR-Datei hinzugefügt. Diese Prozedur ist mit der Prozedur für die Implementierung eines Java-Rechenknotens in einer JAR-Datei identisch (siehe Klassenladen für benutzerdefinierte Knoten.

    Wenn Sie eine JAR-Datei unter Verwendung der Tools implementieren, werden bei der erneuten Implementierung der BAR-Datei, die die JAR-Datei enthält, die Java-Klassen, auf die verwiesen wird, vom neu implementierten Fluss erneut geladen; dasselbe passiert, wenn ein Nachrichtenfluss, der auf eine Java-Klasse verweist, gestoppt und neu gestartet wird. Stellen Sie sicher, dass Sie alle Flüsse, die auf die zu aktualisierende JAR-Datei verweisen, stoppen und neu starten (bzw. erneut implementieren). Damit verhindern Sie, dass einige Flüsse mit der alten Version der JAR-Datei und andere Flüsse mit der neuen Version ausgeführt werden.

    Hinweis: Von den Tools werden nur JAR-Dateien und keine eigenständigen Java-Klassendateien implementiert.

  2. Durch Hinzufügen zum bzw. zur:
    1. Ordner <Arbeitspfad>/shared-classes/ auf der Maschine, auf der der Broker läuft
    2. Umgebungsvariable CLASSPATH auf der Maschine, auf der der Broker läuft

    Diese Prozedur muss manuell ausgeführt werden. Die Tools können für diesen Vorgang nicht verwendet werden.

    Bei diesem Verfahren werden bei einer erneuten Implementierung des Nachrichtenflusses die Java-Klassen, auf die verwiesen wird, nicht erneut geladen, und der Nachrichtenfluss wird nicht gestoppt und neu gestartet. In diesem Fall können die Klassen nur neu geladen werden, indem Sie den Broker stoppen und neu starten.

Damit der Broker eine Java-Klasse finden kann, müssen Sie sicherstellen, da sie sich in einem der oben genannten Verzeichnisse befindet. Wenn der Broker die angegebene Klasse nicht finden kann, löst er eine Ausnahme aus.

Obwohl Ihnen die oben genannten Auswählmöglichkeiten für die Implementierung der JAR-Datei zur Verfügung stehen, bietet die Implementierung der BAR-Datei durch die Tools die größte Flexibilität für die erneute Implementierung der JAR-Datei.

Datenbankroutinen

Datenbankroutinen sind Routinen, die als in Datenbank gespeicherte Prozeduren implementiert werden. Ihre LANGUAGE-Klausel lautet DATABASE, und sie müssen den Routinetyp PROCEDURE haben.

Beim Schreiben gespeicherter Prozeduren in Sprachen wie C müssen Sie NULL-Anzeiger verwenden, um zu gewährleisten, dass Ihre Prozedur die Daten ordnungsgemäß verarbeiten kann.

Obwohl die Datenbankdefinitionen einer gespeicherten Prozedur zwischen den Datenbanken variieren, gilt dies nicht für die ESQL, mit der sie aufgerufen werden. Die Namen, die Parametern im ESQL-Ausdruck zugeordnet werden, müssen nicht mit den in der Datenbank angegebenen Namen übereinstimmen. Der externe Name der Routine - einschließlich aller Paket- oder Containerspezifikationen - muss jedoch seinem definiertem Namen in der Datenbank entsprechen.

Die Klausel DYNAMIC RESULT SET ist nur für Datenbankroutinen zulässig. Sie ist nur erforderlich, wenn eine gespeicherte Prozedur mehrere Ergebnisse zurückgibt. Der Ganzzahlparameter für diese Klausel muss 0 (Null) oder mehr sein und die Anzahl der Ergebnismengen angeben, die zurückgegeben werden sollen.

Die optionale RETURNS-Klausel ist erforderlich, wenn eine gespeicherte Prozedur einen einzelnen skalaren Wert zurückgibt.

Die Klausel EXTERNAL NAME gibt den Namen an, unter dem die Datenbank die Routine kennt. Dies kann ein qualifizierter oder ein nicht qualifizierter Name sein, wobei das Qualifikationsmerkmal der Name des Datenbankschemas ist, in dem die Prozedur definiert ist. Wenn Sie keinen Schemanamen angeben, wird der Benutzername der Datenbankverbindung als das Schema verwendet, in dem sich die Prozedur befindet. Ist die erforderliche Prozedur nicht in diesem Schema vorhanden, müssen Sie einen expliziten Schemanamen angeben - entweder in der Routinedefinition oder in der Anweisung zum Aufrufen der Routine bei Laufzeit. Weitere Informationen zur dynamischen Auswahl des Schemas, das die Routine enthält, finden Sie in der CALL-Anweisung. Wenn ein qualifizierter Name verwendet wird, muss der Name in Anführungszeichen gesetzt werden.

Eine vollständig qualifizierte Routine hat normalerweise folgende Form:
 EXTERNAL NAME "mySchema.myProc";
Gehört die Prozedur jedoch zu einem Oracle-Paket, wird das Paket als Teil des Prozedurnamens behandelt. Geben Sie daher wie folgt einen Schemanamen sowie den Paketnamen an:
EXTERNAL NAME "mySchema.myPackage.myProc";  

Auf diese Weise kann zwar das Schema, aber nicht der Paketname in der CALL-Anweisung dynamisch gewählt werden.

Wenn der Name der Prozedur SQL-Platzhalter enthält (das Prozentzeichen (%) und der Unterstrich (_)), wird die Prozedur vom Broker so geändert, dass sie das Datenbank-Escapezeichen direkt vor dem Platzhalter aufführen. Damit wird sichergestellt, dass die Datenbank die Platzhalter als Literale empfängt. Angenommen, die nachfolgende Klausel wird vom Broker geändert, so wird “mySchema.Proc\_” an die Datenbank übermittelt (vorausgesetzt, dass es sich bei dem Datenbank-Escapezeichen um einen umgekehrten Schrägstrich handelt). ;
EXTERNAL NAME "mySchema.Proc_";  
Für alle externen Prozeduren gelten folgende Einschränkungen:
  • Eine gespeicherte Prozedur kann in der Datenbank nicht überladen werden. Sie gilt als überladen, wenn mehrere Prozeduren mit identischem Namen in demselben Datenbankschema existieren. Wenn der Broker eine überlappende Prozedur feststellt, gibt er eine Ausnahmebedingung aus.
  • Parameter dürfen nicht den Datentyp ESQL REFERENCE, ROW, LIST oder INTERVAL haben.
  • Benutzerdefinierte Namen können nicht als Parameter oder als Rückgabewerte verwendet werden.

Beispiel 1 einer Datenbankroutine

Nachfolgend sehen Sie die einfache ESQL-Definition einer gespeicherten Prozedur, die einen einzelnen skalaren Wert und einen OUT-Parameter zurückgibt:

CREATE PROCEDURE myProc1 (IN P1 INT, OUT P2 INT)
	LANGUAGE DATABASE
	RETURNS INTEGER
	EXTERNAL NAME "myschema.myproc";

Rufen Sie die Routine myProc1 mit folgender ESQL auf:

/*mittels der Aufrufsyntax der CALL-Anweisung*/
CALL myProc1(intVar1, intVar2) INTO intReturnVar3;

/*oder mittels der Funktionsaufrufsyntax*/
SET intReturnVar3 = myProc1(intVar1, intVar2);

Beispiel 2 einer Datenbankroutine

Der nachfolgende ESQL-Code zeigt, wie in DB2 gespeicherte Prozeduren definiert und aufgerufen werden:

ESQL-Definition:
DECLARE inputParm CHARACTER;
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER;

SET inputParm = 'Hello';
SET inputOutputParm = 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  OUT parm2  CHARACTER,
  INOUT parm3 CHARACTER
) EXTERNAL NAME dbSwapParms;

Sie tragen diese gespeicherte Prozedur in DB2 ein, indem Sie das folgende Script in eine Datei (z. B. test1.sql) kopieren

-- DB2 Example Stored Procedure
DROP PROCEDURE dbSwapParms @                                       
CREATE PROCEDURE dbSwapParms
( IN in_param CHAR(32), 
  OUT out_param CHAR(32),
  INOUT inout_param CHAR(32))
LANGUAGE SQL
             BEGIN
SET out_param = inout_param;  
    SET inout_param = in_param;
END @
und an der DB2-Eingabeaufforderung Folgendes ausführen:
db2 -td@ -vf test1.sql 
.
Die Ausführung dieses Codes sollte folgende Ergebnisse liefern:
  • Der Wert des IN-Parameters ändert sich nicht (und kann sich per Definition nicht ändern).
  • Der Wert des OUT-Parameters wird zu "World".
  • Der Wert des INOUT-Parameters wird zu "Hello".

Beispiel 3 einer Datenbankroutine

Der nachfolgende ESQL-Code zeigt, wie in Oracle gespeicherte Prozeduren definiert und aufgerufen werden:

ESQL-Definition:
DECLARE inputParm CHARACTER;
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER;

SET inputParm = 'Hello';
SET inputOutputParm = 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  OUT parm2  CHARACTER,
  INOUT parm3 CHARACTER
) EXTERNAL NAME dbSwapParms;

Sie tragen diese gespeicherte Prozedur in Oracle ein, indem Sie das folgende Script in eine Datei (z. B. test1.sql) kopieren

CREATE OR REPLACE PROCEDURE dbSwapParms 
( in_param IN VARCHAR2 ,
  out_param OUT VARCHAR2, 
  inout_param IN OUT VARCHAR2 )
AS
             BEGIN
  out_param := inout_param;    
  inout_param := in_param;
             END;
/
und an der DB2-Eingabeaufforderung Folgendes ausführen:
sqlplus <Benutzer-ID>/<Kennwort> @test1.sql
Die Ausführung dieses Codes sollte folgende Ergebnisse liefern:
  • Der Wert des IN-Parameters ändert sich nicht (und kann sich per Definition nicht ändern).
  • Der Wert des OUT-Parameters wird zu "World".
  • Der Wert des INOUT-Parameters wird zu "Hello".

Beispiel 4 einer Datenbankroutine

Der nachfolgende ESQL-Code zeigt, wie in SQL Server gespeicherte Prozeduren definiert und aufgerufen werden:

ESQL-Definition:
DECLARE inputParm CHARACTER;
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER;

SET inputParm = 'Hello';
SET inputOutputParm = 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  INOUT parm2  CHARACTER,
  INOUT parm3 CHARACTER
) EXTERNAL NAME dbSwapParms;

Sie tragen diese gespeicherte Prozedur in SQLServer ein, indem Sie das folgende Script in eine Datei (z. B. test1.sql) kopieren

-- SQLServer Example Stored Procedure 
DROP PROCEDURE dbSwapParms 
goCREATE PROCEDURE dbSwapParms
 @in_param     CHAR(32), 
 @out_param    CHAR(32) OUT, 
 @inout_param  CHAR(32) OUT 
AS
  SET NOCOUNT ON
  SET @out_param   = @inout_param 
  SET @inout_param = @in_param 
go
und an der DB2-Eingabeaufforderung Folgendes ausführen:
isql -U<Benutzer-ID> -P<Kennwort> -S<Server> -d<Datenquelle> -itest1.sql
Anmerkung:
  1. SQL Server behandelt OUTPUT-Parameter aus gespeicherten Prozeduren als INPUT/OUTPUT-Parameter.

    Wenn Sie diese als OUT-Parameter in Ihrer ESQL deklarieren, tritt während der Ausführung ein Typabweichungsfehler auf. Zur Verhinderung dieser Abweichung müssen Sie OUTPUT-Parameter von SQL Server in Ihrer ESQL als INOUT-Parameter deklarieren.

  2. Die Option SET NOCOUNT ON sollte aus den folgenden Gründen wie im Beispiel oben für gespeicherte SQL-Prozeduren verwendet werden:
    1. um den Umfang der vom SQLServer an den Broker zurückgegebenen Daten zu reduzieren;
    2. damit Ergebnisse korrekt zurückgegeben werden.
Die Ausführung dieses Codes sollte folgende Ergebnisse liefern:
  • Der Wert des IN-Parameters ändert sich nicht (und kann sich per Definition nicht ändern).
  • Der Wert des OUT-Parameters wird zu "World".
  • Der Wert des INOUT-Parameters wird zu "Hello".

Beispiel 5 einer Datenbankroutine

Der folgende ESQL-Code veranschaulicht, wie gespeicherte SYBASE-Prozeduren definiert und aufgerufen werden:

ESQL-Definition:
DECLARE inputParm CHARACTER;
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER;

SET inputParm = 'Hello';
SET inputOutputParm = 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  INOUT parm2  CHARACTER,
  INOUT parm3 CHARACTER
) EXTERNAL NAME dbSwapParms;

Um diese gespeicherte Prozedur in SYBASE einzutragen, müssen Sie das folgende Script in eine Datei (z. B. test1.sql) kopieren

-- Gespeicherte SYBASE-Prozeduren - Beispiel
DROP PROCEDURE dbSwapParms 
goCREATE PROCEDURE dbSwapParms
 @in_param     CHAR(32), 
 @out_param    CHAR(32) OUT, 
 @inout_param  CHAR(32) OUT 
AS
  SET @out_param   = @inout_param 
  SET @inout_param = @in_param 
go
und an der DB2-Eingabeaufforderung Folgendes ausführen:
isql -U<Benutzer-ID> -P<Kennwort> -S<Server> -d<Datenquelle> -itest1.sql
Anmerkung: SYBASE handhabtOUTPUT-Parameter in gespeicherten Prozeduren wie INPUT/OUTPUT-Parameter.

Wenn Sie diese als OUT-Parameter in Ihrer ESQL deklarieren, tritt während der Ausführung ein Typabweichungsfehler auf. Um diese Abweichung zu verhindern, müssen Sie die OUTPUT-Parameter von SYBASE in ESQL als INOUT-Parameter deklarieren.

Die Ausführung dieses Codes sollte folgende Ergebnisse liefern:
  • Der Wert des IN-Parameters ändert sich nicht (und kann sich per Definition nicht ändern).
  • Der Wert des OUT-Parameters wird zu "World".
  • Der Wert des INOUT-Parameters wird zu "Hello".

Beispiel 6 einer Datenbankroutine

Dieses Beispiel zeigt, wie Sie eine gespeicherte Prozedur aufrufen, die zwei Ergebnismengen und einen OUT-Parameter zurückgibt:

CREATE PROCEDURE myProc1 (IN P1 INT, OUT P2 INT)
  LANGUAGE DATABASE
  	DYNAMIC RESULT SETS 2
  	EXTERNAL NAME "myschema.myproc";

Rufen Sie myProc1 mit folgender ESQL auf:

/* using a field reference */
CALL myProc1(intVar1, intVar2, Environment.RetVal[], OutputRoot.XML.A[])/* using a reference variable*/
CALL myProc1(intVar1, intVar2, myReferenceVariable.RetVal[], myRef2.B[])
Zugehörige Konzepte
Übersicht zu ESQL
Zugehörige Tasks
ESQL erstellen
Gespeicherte Prozeduren aufrufen
Zugehörige Verweise
Syntaxdiagramme: verfügbare Typen
ESQL-Anweisungen
CALL-Anweisung
Tabelle für die Zuordnung von ESQL- zu Java-Datentypen
Bemerkungen | Marken | Downloads | Bibliothek | Unterstützung | Rückmeldung
Copyright IBM Corporation 1999, 2006 Letzte Aktualisierung: 23. Aug. 2006
ak04970_