WebSphere Message Broker, Versión 8.0.0.5 Sistemas operativos: AIX, HP-Itanium, Linux, Solaris, Windows, z/OS

Consulte la información sobre la última versión del producto en IBM Integration Bus, Versión 9.0

Sentencia CREATE PROCEDURE

La sentencia CREATE PROCEDURE define una función o un procedimiento que se puede llamar.

También puede utilizar la separa definir una función o un procedimiento que se puede llamar, que también se conoce como rutina.

Cada rutina tiene un nombre, que debe ser exclusivo dentro del esquema al que pertenece. Por tanto, no se pueden sobrecargar los nombres de las rutinas; si el intermediario detecta que se ha sobrecargado un nombre de rutina, genera una excepción.

Sintaxis

Leer el esquema de sintaxisOmitir el esquema de sintaxis visual
>>-CREATE--| TipoRutina |--NombreRutina------------------------->

>--(--| ListaParámetros |--)--+-----------------+--------------->
                              '-| TipoRetorno |-'   

>--+--------------+--+------------------------+----------------->
   '-| Lenguaje |-'  '-| ConjuntoResultados |-'   

>--| CuerpoRutina |--------------------------------------------><

TipoRutina

|--+-FUNCTION--+------------------------------------------------|
   '-PROCEDURE-'   

ListaParámetros

   .-,-----------------.   
   V                   |   
|----+---------------+-+----------------------------------------|
     '-| Parámetro |-'     

Parámetro

        (1)                                                   
|--+-IN-----+--NombreParámetro--+-+----------+--TipoDatos-+----->
   +-OUT----+                   | '-CONSTANT-'            |   
   '-INOUT--'                   |           (2)           |   
                                +-NAMESPACE---------------+   
                                '-NAME--------------------'   

   .-NULLABLE-.   
>--+----------+-------------------------------------------------|
   '-NOT NULL-'   

TipoRetorno

                       .-NULLABLE-.   
|--RETURNS--TipoDatos--+----------+-----------------------------|
                       '-NOT NULL-'   

Lenguaje

|--LANGUAGE--+-ESQL---------+-----------------------------------|
             |          (3) |   
             +-DATABASE-----+   
             +-.NET---------+   
             +-CLR----------+   
             '-JAVA---------'   

ConjuntoResultados

|--DYNAMIC RESULT SETS--entero----------------------------------|

CuerpoRutina

|--+-Sentencia-------------------------------------------------------+--|
   '-EXTERNAL--NAME--NombreRutinaExterna--+------------------------+-'   
                                          +-.NetTypeInfo-----------+     
                                          '-JavaClassLoaderService-'     

.NetTypeInfo

|--ASSEMBLY--NombreEnsamblado----------------------------------->

   .-------------------------------------------.   
   V  (4)                                      |   
>--------+-----------------------------------+-+----------------|
         +-APPDOMAIN--NombreDominio----------+     
         +-VERSION--Versión------------------+     
         +-CULTURE--ContextoCultural---------+     
         '-PUBLICKEYTOKEN--SeñalClavePública-'     

JavaClassLoaderService

|--CLASSLOADER--NombreServicioConfigurableCargadorClases--------|

Notas:
  1. Si el tipo de rutina es FUNCTION, el indicador de dirección (IN, OUT o INOUT) es opcional para cada parámetro. Sin embargo, para fines de documentación, en programación se recomienda especificar un indicador de dirección para todas las nuevas rutinas; si no especifica la dirección, se utiliza un valor predeterminado de IN.
  2. Cuando se utiliza la cláusula NAMESPACE o NAME, su valor es implícitamente CONSTANT y del tipo CHARACTER. Para obtener información acerca de cómo utilizar las variables CONSTANT, consulte Sentencia DECLARE.
  3. Si el tipo de rutina es FUNCTION, no se puede especificar el lenguaje (LANGUAGE) DATABASE.
  4. Cada uno sólo se puede especificar una vez.

Direcciones de parámetros

Los parámetros que se pasan a las rutinas siempre tienen una dirección asociada a ellos, que es uno de los tipos siguientes:
IN
La rutina no puede cambiar el valor del parámetro. Se permite el valor NULL para el parámetro y puede pasarse a la rutina.
OUT
Cuando la rutina llamada lo recibe, el parámetro pasado a la rutina siempre tiene el valor NULL del tipo de datos correcto. Este valor se establece independientemente del valor que tenía antes de llamar a la rutina. La rutina puede cambiar el valor del parámetro.
INOUT
INOUT es un parámetro IN y OUT a la vez. Pasa un valor a la rutina y el valor que se ha pasado puede cambiarlo la rutina. Se permite el valor NULL para el parámetro y puede pasarse dentro y fuera de la rutina.
NULLABLE
Esta cláusula opcional indica que el valor del parámetro puede contener un valor NULL. NULL es la cláusula predeterminada si se omite esta cláusula, a menos que se especifique la cláusula NOT NULL.
NOT NULL
Esta cláusula opcional indica que el valor del parámetro no puede contener un valor NULL. Si un parámetro se marca como NOT NULL y se pasa un valor NULL en la llamada, se emite una excepción. Nota: en la actualidad esta cláusula sólo se puede utilizar con LANGUAGE CLR o LANGUAGE .NET.

Si el tipo de rutina es FUNCTION, el indicador de dirección (IN, OUT, INOUT) es opcional para cada parámetro. Sin embargo, en programación se recomienda especificar un indicador de dirección para todas las nuevas rutinas de cualquier tipo.

Las variables ESQL que se declaran como CONSTANT (o las referencias a las variables declaradas como CONSTANT) no pueden tener la dirección OUT o INOUT.

Rutinas ESQL

Las rutinas ESQL están escritas en ESQL y tienen una cláusula LANGUAGE de ESQL. El cuerpo de una rutina ESQL normalmente es una sentencia compuesta de la forma BEGIN… END, que contiene múltiples sentencias para procesar los parámetros que han pasado a la rutina.

Ejemplo 1 de ESQL

El ejemplo siguiente muestra el mismo procedimiento que en Ejemplo 1 de rutina de base de datos, pero se implementa como una rutina ESQL y no como un procedimiento almacenado. La sintaxis CALL y los resultados de esta rutina son los mismos que los que se encuentran en:
CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  OUT parm2  CHARACTER,
  INOUT parm3 CHARACTER )
BEGIN
   SET parm2 = parm3;
   SET parm3 = parm1;
 END; 

Ejemplo 2 de ESQL

Este procedimiento de ejemplo muestra el uso repetitivo de una rutina ESQL. Analiza un árbol, visitando todos los lugares desde un punto de partida concreto, y genera informes sobre lo que ha encontrado:

SET OutputRoot.MQMD = InputRoot.MQMD;

  DECLARE answer CHARACTER;
  SET answer = '';

  CALL navigate(InputRoot.XMLNS, answer);
  SET OutputRoot.XMLNS.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;

Cuando se proporciona el siguiente mensaje de entrada:

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

el procedimiento genera la salida siguiente que se ha formateado manualmente:

  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

Rutinas .NET

Una rutina .NET se implementa como un método .NET y tiene una cláusula LANGUAGE de .NET o CLR. Para rutinas .NET, el NombreRutinaExterna debe contener el nombre de clase y el nombre de método del método .NET que se va a invocar. Especifique el NombreRutinaExterna como en este ejemplo:

>>--"-- nombreClase---.---nombreMétodo--"--------------><
Donde nombreClase identifica la clase que contiene el método y nombreMétodo identifica el método a invocar. Si la clase forma parte de un Espacio de nombres o es una clase anidad, la parte del identificador de clase debe incluir todos los nombres de Espacio de nombres y clase anidada; por ejemplo, "IBM.Broker.test.MyOuterClass.MyNestedClass.MyMethod"

Para encontrar la clase .NET, el intermediario busca la GAC y la ubicación base DominioAplic del ensamblado especificado.

Cualquier método .NET que desee invocar debe ser un método estático público. Además, todos los parámetros deben aparecer listados en Tablas de correlación de tipo de datos de ESQL a .NET. Asimismo, si el método tiene un tipo de retorno, el tipo de retorno debe aparecer listado en la tabla de correlaciones de tipos de datos IN.

La firma de los métodos .NET debe coincidir con la declaración de las rutinas ESQL del método. También debe cumplir las reglas siguientes:
  • Asegúrese de que el nombre de método .NET, incluido el nombre de clase y los calificadores de Espacio de nombres coincide con el EXTERNAL NAME de los procedimientos ESQL.
  • Si el método .NET no tiene un tipo de retorno, no coloque una cláusula RETURNS en la definición de las rutinas ESQL. Y a la inversa; si el método .NET si que tiene un tipo de retorno, debe colocar una cláusula RETURNS en la definición de las rutinas ESQL.
  • Asegúrese de que cada tipo de parámetro y dirección coincide con la declaración de ESQL, de acuerdo con las reglas listadas en Tablas de correlación de tipo de datos de ESQL a .NET.
  • Asegúrese de que el tipo de retorno de los métodos coincide con el tipo de datos de la cláusula RETURNS.
  • Coloque EXTERNAL NAME entre comillas porque debe contener al menos "Class.Method".
  • Si desea invocar un método .NET sobrecargado, debe crear una definición ESQL por separado para cada método sobrecargado y otorgar a cada definición ESQL un nombre de rutina exclusivo.
Información del tipo .NET
La cláusula en la sección Información del tipo .NET sólo se aplica a las rutinas LANGUAGE .NET.
ASSEMBLY
ASSEMBLY indica el ensamblado .NET donde reside el método que se va a invocar. Si el ensamblado reside en la GAC, puede ser simplemente el nombre de ensamblado (por ejemplo, “MiEnsamblado”). Sin embargo, si el ensamblado no está en la GAC, necesita contener la vía de acceso completa al ensamblado.
APPDOMAIN
Este parámetro proporciona el nombre de APPDOMAIN en el que se carga el ensamblado y se ejecuta el método. Si se omite esta cláusula, APPDOMAIN se establece en el nombre de la aplicación a la que pertenece el flujo. Si el flujo no pertenece a una aplicación, APPDOMAIN se establece en el nombre del flujo de mensajes.
VERSION
Proporciona la versión exacta del ensamblado que se va a cargar. Si se omite la versión, se utiliza la primera versión del ensamblado especificado.
CULTURE
Proporciona la posibilidad de especificar un contexto cultural exacto del ensamblado. El valor predeterminado es utilizar el contexto cultural “neutro”.
PUBLICKEYTOKEN
Si el ensamblado que se va a cargar reside en la GAC, se tiene que proporcionar la señal de clave pública. Sin embargo, si el ensamblado no reside en la GAC, esta cláusula es opcional. Cuando se busca un ensamblado, el orden de búsqueda es el definido con la infraestructura .NET, cuyos detalles completos aparecen listados en MSDN. Sin embargo, la versión abreviada indica lo siguiente: si el nombre de ensamblado no está completo, se utiliza la base del DominoAplic. Si el nombre de ensamblado está completo (es decir, se han especificado la versión y la señal de clave pública), se busca en la GAC antes que la carpeta base Dominios aplic.

Ejemplo 1 de rutina .NET

Define un procedimiento que representa un Método .NET que devuelve un valor System:String con tres parámetros de direcciones variadas.
CREATE PROCEDURE Swap ( 
       IN a INT NOT NULL, 
       OUT b INT NOT NULL, 
       INOUT c INT NOT NULL ) RETURNS CHARACTER NOT NULL
LANGUAGE .NET
EXTERNAL NAME "FunctionTests.SwapString"
ASSEMBLY "C:\coding\test projects\MyAssembly"
APPDOMAIN "MyDomain";
Se puede utilizar el siguiente procedimiento ESQL para invocar a Swap.
CALL Swap( intVar1, intVar2, intVar3 ) INTO ReturnVar;
-- o
SET ReturnVar = Swap ( intVar1, intVar2, intVar3);

Ejemplo 2 de rutina .NET

Define un procedimiento que representa un Método .NET que no devuelve ningún valor con tres parámetros anulables de direcciones variadas.

CREATE PROCEDURE SwapNullable ( 
       IN a INTEGER NULLABLE, 
       OUT b INTEGER NULLABLE, 
       INOUT c INTEGER NULLABLE )
LANGUAGE CLR
EXTERNAL NAME "FunctionTests.SwapStringNullable"
ASSEMBLY "MyAssembly2"
APPDOMAIN "MyDomain";
Debe utilizarse el siguiente procedimiento ESQL para invocar a SwapNullable.
CALL SwapNullable(intVar1, intVar2, intVar3);

Código de ejemplo para diversos lenguajes .NET que proporcionan métodos para los dos ejemplos

C#

public class FunctionTests
{

  public static string Swap(int pIn, out int pOut, ref int pInout)
  {
    pOut = pInout;
    pInout = pIn;
    return "Finished";
  }

  public static void SwapNullable(long? pIn, out long? pOut, ref long? pInout)
  {
    pOut = pInout;
    pInout = pIn;
  }

}

VB

Public Class FunctionTests

  Shared Function Swap(ByVal pIn As Integer, <Out()> ByRef pOut As Integer, ByRef pInout As Integer) As String
    pOut = pInout
    pInout = pIn
    Return "Finished"
  End Function

  Shared Sub SwapNullable(ByVal pIn As Long?, ByRef pOut As Long?, ByRef pInout As Long?)
    pOut = pInout
    pInout = pIn
  End Sub

End Class

F#

module FunctionTests

  let Swap( pIn : int, [<Out>] pOut : byref<int> ,  pInOut : byref<int> ) = (
    pOut <- pInout
    pInout <- pIn
    let temp = "Finished"
    temp
  )

  let SwapNullable(  pIn : Nullable<int64>, [<Out>] pOut : byref<Nullable<int64>> ,  pInOut : byref<Nullable<int64>> ) = (
    pOut <- pInout
    pInout)
  )

C++ / CLi

public ref class FunctionTests
{
public:

  static String^ Swap(int pIn, [Out] int% pOut, int% pInout)
  {
    pOut = pInout;
    pInout = pIn;
    String^ temp = "Finished";
    return temp;
  }

  static void SwapNullable(Nullable<long long> pIn, [Out] Nullable<long long>% pOut, Nullable<long long>% pInout)
  {
    pOut = pInout;
    pInout = pIn;
  }
}

Rutinas Java

Una rutina Java™ se implementa como un método Java y tiene una cláusula LANGUAGE de JAVA. Para rutinas Java, NombreRutinaExterna debe contener el nombre de clase y el nombre del método Java que se va a llamar. Especifique el NombreRutinaExterna como en el ejemplo siguiente:
>>--"-- nombreClase---.---nombreMétodo--"--------------><
donde nombreClase identifica la clase que contiene el método y nombreMétodo identifica el método a invocar. Si la clase forma parte de un paquete, la parte correspondiente al identificador de clase debe incluir el prefijo del paquete completo; por ejemplo, "com.ibm.broker.test.MyClass.myMethod".

Para encontrar la clase Java, el intermediario utiliza el método de búsqueda que se describe en Despliegue de clases Java.

Cualquier método Java que desee invocar debe tener la siguiente signatura básica:
public static <return-type> <method-name> (<parámetros 0 - N>)

Donde <tipo-retorno> debe estar en la lista de tipos de datos IN de Java de la tabla de Correlación de tipo de datos ESQL a Java (excluyendo el tipo REFERENCE, que no está permitido como valor de retorno) o el tipo de datos void (vacío) de Java. Los tipos de datos de parámetros también deben estar en la tabla Correlación de tipo de datos ESQL a Java. Además, no se permite que el método Java tenga la cláusula exception throws en su firma.

La firma de los métodos Java debe coincidir con la declaración de las rutinas ESQL del método. También debe cumplir las reglas siguientes:
  • Asegúrese de que el nombre de método Java, incluyendo el nombre de clase y los calificadores de paquetes, coincide con el EXTERNAL NAME de los procedimientos.
  • Si el tipo de retorno Java es void, no ponga una cláusula RETURNS en la definición de las rutinas ESQL. Y a la inversa; si el tipo de retorno Java no es void, debe colocar una cláusula RETURNS en la definición de las rutinas ESQL.
  • Asegúrese de que cada tipo de parámetro coincide con la declaración ESQL, según las normas que aparecen listadas en la tabla en Correlación de tipo de datos ESQL a Java.
  • Asegúrese de que el tipo de retorno de los métodos coincide con el tipo de datos de la cláusula RETURNS.
  • Coloque EXTERNAL NAME entre comillas porque debe contener al menos "class.method".
  • Si desea invocar un método Java sobrecargado, debe crear una definición de ESQL independiente para cada método sobrecargado y proporcionar a cada definición de ESQL un nombre de rutina exclusivo.

La cláusula de la sección JavaClassLoader sólo se aplica a las rutinas LANGUAGE JAVA. La cláusula CLASSLOADER es opcional; si no especifica esta cláusula, el cargador de clases EGShared carga la clase Java. Para obtener más información, consulte Carga de clases del nodo JavaCompute y Servicio configurable JavaClassLoader.

Puede utilizar la API de nodo Java definido por el usuario en el método Java, si cumple las restricciones documentadas en Restricciones en rutinas Java. Para obtener más información sobre cómo utilizar la API Java, consulte Compilación de un nodo Java definido por el usuario.

Ejemplo 1 de rutina Java

Esta rutina contiene tres parámetros de diversas direcciones y devuelve un entero, que se correlaciona a un tipo de retorno Java de java.lang.Long.

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

Puede utilizar el siguiente procedimiento ESQL para invocar amyProc1:

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

Ejemplo 2 de rutina Java

Esta rutina contiene tres parámetros de diversas direcciones y tiene un tipo de retorno Java de void.

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

Debe utilizar el siguiente procedimiento ESQL para invocar myProc2:

CALL myProc2(intVar1, intVar2, intVar3);

La siguiente clase Java proporciona un método para cada uno de los ejemplos Java anteriores:

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) { ... }

 /* Cuando se llama a cualquiera de estos métodos:
    P1 puede ser o no NULL (dependiendo del valor de intVar1).
    P2[0] siempre es NULL (sea cual sea el valor de intVar2).
    P3[0] puede ser o no NULL (dependiendo del valor de intVar3).  
    Es lo mismo que con las rutinas LANGUAGE ESQL. 
    Estos métodos pueden devolver:
         intVar1 sin modificar
         intVar2 modificado o todavía con el valor NULL
         intVar3 modificado o todavía con el mismo valor
     Es lo mismo que con las rutinas LANGUAGE ESQL.
     
    Cuando myMethod1 devuelve: intReturnVar3 puede ser  NULL (si
    el método devuelve NULL) o contiene el valor devuelto por el 
    método.
 */
}

Ejemplo 3 de rutina Java

El siguiente ejemplo tiene una cláusula LANGUAGE de JAVA y especifica un EXTERNAL NAME para un método Java denominado myMethod1 en la clase com.ibm.broker.test.MyClass. También especifica un servicio configurable JavaClassLoader denominado myClassLoader para utilizarlo para cargar la clase Java com.ibm.broker.test.MyClass.
CREATE FUNCTION myMethod1 ( IN P1 INTEGER, IN P2 INTEGER )
  RETURNS INTEGER
  LANGUAGE JAVA
  EXTERNAL NAME "com.ibm.broker.test.MyClass.myMethod1"
  CLASSLOADER "myClassLoader";

Correlación de tipo de datos ESQL a Java

La tabla siguiente resume las correlaciones de ESQL a Java.
Notas:
  • Sólo se pasan a Java los wrappers escalares Java.
  • Los tipos escalares ESQL se correlacionan con los tipos de datos Java como wrappers de objetos o como matrices de wrappers de objetos, dependiendo de la dirección del parámetro de procedimiento. Cada matriz de wrapper contiene exactamente un elemento.
  • Los wrappers de objetos escalares se utilizan para que puedan pasarse valores NULL a y desde los métodos Java.
Tipos de datos ESQL 1 Tipos de datos Java IN Tipos de datos Java INOUT y OUT
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 No soportado No soportado
BOOLEAN java.lang.Boolean java.lang.Boolean[]
REFERENCE (a un árbol de mensaje) 3 4 5 6 com.ibm.broker.plugin.MbElement com.ibm.broker.plugin.MbElement[] (Soportado para INOUT. No soportado para OUT)
ROW No soportado No soportado
LIST No soportado No soportado
  1. Las variables que se declaran como CONSTANT (o las referencias a las variables que se declaran como CONSTANT) no pueden tener la dirección INOUT u OUT.
  2. El huso horario establecido en la variable Java no es importante, el huso horario necesario se obtiene en el ESQL de salida.
  3. l parámetro de referencia no puede ser NULL cuando se pasa a un método Java.
  4. La referencia no puede tener la dirección OUT cuando se pasa a un método Java.
  5. Si se vuelve a pasar un MbElement de Java ESQL como un parámetro INOUT, debe apuntar a una ubicación en el mismo árbol de mensaje al que apuntaba el MbElement que se ha pasado en el método Java.

    Por ejemplo, si se pasa una referencia ESQL a OutputRoot.XML.Test a un método Java como un MbElement INOUT, pero se vuelve a pasar un MbElement diferente a ESQL cuando se devuelve la llamada, el elemento diferente también debe apuntar a algún lugar del árbol OutputRoot.

  6. Un MbElement no se puede devolver desde un método Java con la cláusula RETURNS, ya que ninguna rutina ESQL puede devolver una referencia. No obstante, un elemento MbElement se puede devolver como un parámetro de dirección INOUT, dependiendo de las condiciones descritas en el punto 5.

Puede utilizarse una referencia (REFERENCE) a una variable escalar en la llamada (CALL) de un método Java, siempre que el tipo de datos de la variable a la que REFERENCE hace referencia coincida con el tipo de datos correspondiente en la signatura del programa Java.

Restricciones en rutinas Java

Se aplican las restricciones siguientes a las rutinas Java llamadas desde ESQL:
  • El método Java debe tener seguridad de hebras (reentrante).
  • Las conexiones de base de datos deben ser JDBC tipo 2 o tipo 4. Además, las operaciones de base de datos no forman parte de una transacción de intermediario y, por consiguiente, no pueden ser controladas por un coordinador de recursos externo (como es el caso en un entorno XA).
  • La API de nodo definido por el usuario de Java sólo debe utilizarla la misma hebra que ha invocado el método Java.

    Puede crear hebras dentro del método. Sin embargo, las hebras creados no deben utilizar las API de Java y se debe devolver el control al intermediario.

    Todas las restricciones que se aplican al uso de la API de Java también se aplican a los métodos API Java llamados desde ESQL.

  • Los métodos Java que se llaman desde ESQL no deben utilizar la clase MbNode. Por tanto, no pueden crear objetos de tipo MbNode, ni llamar a ninguno de los métodos de un objeto MbNode existente.
  • El trabajo de WebSphere MQ o JMS realizado en un método Java llamado desde ESQL debe realizarse siguiendo las directrices para realizar el trabajo de WebSphere MQ y JMS en un nodo definido por el usuario. Consulte Planificación de nodos de entrada definidos por el usuario.

Despliegue de clases Java

Puede desplegar las clases Java en un intermediario dentro de un archivo JAR (Java Archive), utilizando uno de los dos métodos siguientes:
  1. Añada el archivo JAR al archivo de archivado de intermediario (BAR)

    El método más eficiente y flexible de desplegar en el intermediario consiste en añadir el archivo JAR al archivo BAR. Puede realizar esta acción manualmente o automáticamente utilizando WebSphere Message Broker Toolkit.

    Si WebSphere Message Broker Toolkit encuentra la clase Java correcta en un proyecto Java al que se hace referencia abierto en el espacio de trabajo, compila automáticamente la clase Java en un archivo JAR y lo añade al archivo BAR. Este procedimiento es el mismo que se sigue para desplegar un nodo JavaCompute en un JAR, tal como se describe en Carga de clases de nodos definidos por el usuario.

    Al desplegar un archivo JAR desde WebSphere Message Broker Toolkit, el flujo que se ha vuelto a desplegar vuelve a cargar el archivo JAR contenido en el archivo BAR.

    Los archivos también se vuelven a cargar si se detiene y se reinicia el flujo de mensajes que hace referencia a una clase Java. Asegúrese de detener y reiniciar (o volver a desplegar) todos los flujos que hacen referencia al archivo JAR que desea actualizar. Esta acción evita el problema de algunos flujos ejecutándose con la versión antigua del archivo JAR y otros flujos ejecutándose con la versión nueva.

    WebSphere Message Broker Toolkit sólo despliega archivos JAR; no despliega archivos de clase Java autónomos.

  2. Almacenar el archivo JAR en una de las ubicaciones siguientes:
    1. La carpeta víaAccesoTrabajo/shared-classes/ de la máquina que ejecuta el intermediario
    2. La variable de entorno CLASSPATH del sistema que ejecuta el intermediario

    Debe completar esta acción manualmente; no puede utilizar WebSphere Message Broker Toolkit.

    En este método, al desplegar de nuevo el flujo de mensajes no se vuelven a cargar las clases Java a las que se hace referencia; éstas tampoco se vuelven a cargar al detener y reiniciar el flujo de mensajes. En este caso, la única manera de volver a cargar las clases es detener y reiniciar el intermediario mismo.

Para permitir que el intermediario encuentre una clase Java, asegúrese de que esté en una de las ubicaciones anteriores. Si el intermediario no puede encontrar la clase especificada, genera una excepción.

Aunque dispone de las opciones mostradas anteriormente cuando desplegó el archivo JAR, si utiliza WebSphere Message Broker Toolkit para desplegar el archivo BAR obtendrá la máxima flexibilidad cuando vuelva a desplegar el archivo JAR.

Rutinas de base de datos

Las rutinas de base de datos se implementan como procedimientos almacenados de base de datos. Las rutinas de base de datos tienen una cláusula LANGUAGE de DATABASE y deben tener un tipo de rutina PROCEDURE.

Cuando escriba procedimientos almacenados en lenguajes como C, debe utilizar indicadores NULL para asegurarse de que el procedimiento pueda procesar correctamente los datos.

Aunque las definiciones de base de datos de un procedimiento almacenado varían entre las bases de datos, el ESQL utilizado para invocarlas no varía. Los nombres asignados a los parámetros en ESQL no coinciden con los nombre proporcionados en el extremo de la base de datos. No obstante, el nombre externo de la rutina, incluida cualquier especificación de paquete o contenedor, debe coincidir con su nombre definido en la base de datos.

La cláusula DYNAMIC RESULT SETS sólo está permitida para rutinas de base de datos. Sólo es necesaria si un procedimiento almacenado devuelve uno o más conjuntos de resultados. El parámetro de entero de esta cláusula debe ser 0 (cero) o más y especifica el número de conjuntos de resultados que se deben devolver.

Se necesita la cláusula RETURNS opcional si un procedimiento almacenado devuelve un solo valor escalar.

La cláusula EXTERNAL NAME especifica el nombre por el que la base de datos conoce a la rutina. Puede ser un nombre calificado o no calificado, en el que el calificador es el nombre del esquema de base de datos donde se ha definido el procedimiento. Si no proporciona un nombre de esquema, se utiliza el nombre de usuario de la conexión de base de datos como el esquema en el que ubicar el procedimiento. Si el procedimiento necesario no existe en este esquema, debe proporcionar un nombre de esquema explícito, bien en la definición de la rutina o en la llamada (CALL) a la rutina en tiempo de ejecución. Para obtener más información sobre la elección dinámica del esquema que contiene la rutina, consulte Sentencia CALL. Cuando se utiliza un nombre cualificado, el nombre de escribirse entre comillas.

Normalmente, una rutina totalmente calificada tiene el formato:
 EXTERNAL NAME "mySchema.myProc";
Sin embargo, si el procedimiento pertenece a un paquete Oracle, el paquete se trata como parte del nombre del procedimiento. Por tanto, debe proporcionar un nombre de esquema y un nombre de paquete, en el formato:
EXTERNAL NAME "mySchema.myPackage.myProc";  

Este formato permite elegir dinámicamente el esquema, pero no el nombre de paquete, en la sentencia CALL.

Si el nombre del procedimiento contiene caracteres comodín de SQL (que son el carácter de porcentaje (%) y el de subrayado (_)), el intermediario modifica el nombre del procedimiento para que incluya el carácter de escape de base de datos justo antes de cada carácter comodín. Esta técnica asegura que la base de datos reciba los caracteres comodín como caracteres literales. Por ejemplo, suponiendo que el carácter de escape de base de datos es una barra inclinada invertida, el intermediario modifica la cláusula de forma que "mySchema.Proc\_" se pasa a la base de datos.
EXTERNAL NAME "mySchema.Proc_";  
Todos los procedimientos externos tienen las restricciones siguientes:
  • Un procedimiento almacenado no puede estar duplicado en el lado de la base de datos. Se considera que un procedimiento almacenado está duplicado si hay más de un procedimiento con el mismo nombre en el mismo esquema de base de datos. Si el intermediario detecta que se ha sobrecargado un procedimiento, genera una excepción.
  • Los parámetros no pueden ser de los tipos de datos ESQL REFERENCE, ROW, LIST o INTERVAL.
  • Los tipos definidos por el usuario no se pueden utilizar como parámetros o como valores de retorno.
Para las rutinas LANGUAGE DATABASE, NombreRutinaExterna no es opcional y contiene el nombre del esquema, el nombre del paquete y el nombre del procedimiento de la rutina que se va a llamar. Especifique el NombreRutinaExterna de la siguiente manera:
>>--"nombreEsquema---.---nombrePaquete---.---nombreProcedimiento--"--------------><
donde:
  • nombreEsquema es opcional.
  • nombrePaquete es opcional y se aplica únicamente a los orígenes de datos Oracle. Si se suministra un nombrePaquete se debe suministrar un nombreEsquema.
  • nombreProcedimiento no es opcional.

Ejemplo 1 de rutina de base de datos

El ejemplo siguiente muestra una definición ESQL de un procedimiento almacenado que devuelve un valor escalar individual y un parámetro OUT:

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

Utilice este ESQL para invocar la rutina myProc1:

/*utilizando la sintaxis de invocación de sentencia CALL*/
CALL myProc1(intVar1, intVar2) INTO intReturnVar3;

/*o utilizando la sintaxis de invocación de función*/
SET intReturnVar3 = myProc1(intVar1, intVar2);

Ejemplo 2 de rutina de base de datos

El siguiente código ESQL muestra cómo definir y llamar a procedimientos almacenados de DB2:

Definición
de ESQL:
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
)
LANGUAGE DATABASE
EXTERNAL NAME dbSwapParms;

Para registrar este procedimiento almacenado en DB2, copie el siguiente script en un archivo (por ejemplo test1.sql)

-- Procedimiento almacenado de ejemplo de DB2
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 @
Ahora, ejecute el archivo desde al indicador de mandatos de DB2:
db2 -td@ -vf test1.sql 
Al ejecutarse este código, puede esperarse el siguiente resultado:
  • El valor del parámetro IN no cambia (y no puede hacerlo, por definición).
  • El valor del parámetro OUT pasa a ser "World".
  • El valor del parámetro INOUT pasa a ser "Hello".

Ejemplo 3 de rutina de base de datos

El siguiente código ESQL muestra cómo definir y llamar a procedimientos almacenados de Oracle:

Definición
de ESQL:
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
)
LANGUAGE DATABASE
EXTERNAL NAME dbSwapParms;

Para registrar este procedimiento almacenado en Oracle, copie el script siguiente en un archivo (por ejemplo, test1.sql)

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; 
/
Ahora, ejecute el archivo:
sqlplus IDusuario/contraseña  @test1.sql
Al ejecutarse este código, puede esperarse el siguiente resultado:
  • El valor del parámetro IN no cambia (y no puede hacerlo, por definición).
  • El valor del parámetro OUT pasa a ser "World".
  • El valor del parámetro INOUT pasa a ser "Hello".

Ejemplo 4 de rutina de base de datos

El siguiente código ESQL muestra cómo definir y llamar a procedimientos almacenados de SQL Server:

Definición
de ESQL:
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
)
LANGUAGE DATABASE
EXTERNAL NAME dbSwapParms;

Para registrar este procedimiento almacenado en SQL Server, copie el siguiente script en un archivo (por ejemplo test1.sql)

-- Procedimiento almacenado de ejemplo de SQLServer 
DROP PROCEDURE dbSwapParms 
go                                                   
CREATE 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 
Ahora ejecute el archivo:
isql -UIDusuario -Pcontraseña -Sservidor -dorigendatos -itest1.sql

SQL Server trata los parámetros OUTPUT de los procedimientos almacenados como parámetros INPUT/OUTPUT. Si los declara como parámetros OUT en el ESQL, se encontrará con un error de discrepancia entre tipos durante la ejecución. Para evitar esa discrepancia, debe declarar los parámetros OUTPUT de SQL Server como parámetros INOUT en el ESQL.

Utilice la opción SET NOCOUNT ON, tal como se muestra en el ejemplo anterior, con procedimientos almacenados SQL por las razones siguientes:
  1. Para limitar la cantidad de datos devueltos desde SQL Server al intermediario.
  2. Para permitir que los conjuntos de resultados se devuelvan correctamente.
Al ejecutarse este código, puede esperarse el siguiente resultado:
  • El valor del parámetro IN no cambia (y no puede hacerlo, por definición).
  • El valor del parámetro OUT pasa a ser "World".
  • El valor del parámetro INOUT pasa a ser "Hello".

Ejemplo 5 de rutina de base de datos

El siguiente código ESQL demuestra cómo definir y llamar a los procedimientos almacenados de Sybase:

Definición
de ESQL:
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
)
LANGUAGE DATABASE
EXTERNAL NAME dbSwapParms;

Para registrar este procedimiento almacenado en Sybase, copie el script siguiente en un archivo (por ejemplo, test1.sql)

-- Procedimiento almacenado de ejemplo de SYBASE 
DROP PROCEDURE dbSwapParms 
go                                                   
CREATE 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 
Ahora ejecute el archivo:
isql -U<IDusuario> -P<contraseña> -S<servidor> -D<origendatos> -itest1.sql

Sybase trata los parámetros OUTPUT de los procedimientos almacenados como parámetros INPUT/OUTPUT. Si los declara como parámetros OUT en el ESQL, se encontrará con un error de discrepancia entre tipos en la ejecución. Para evitar esa discrepancia, declare los parámetros Sybase OUTPUT como parámetros INOUT en ESQL.

Al ejecutarse este código, puede esperarse el siguiente resultado:
  • El valor del parámetro IN no cambia (y no puede hacerlo, por definición).
  • El valor del parámetro OUT pasa a ser "World".
  • El valor del parámetro INOUT pasa a ser "Hello".

Ejemplo 6 de rutina de base de datos

El siguiente código ESQL muestra cómo definir y llamar a procedimientos almacenados de Informix:

Definición
de ESQL:
DECLARE inputParm CHARACTER 'Hello';
DECLARE outputParm CHARACTER;
DECLARE inputOutputParm CHARACTER 'World';
CALL swapParms( inputParm, outputParm, inputOutputParm );

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

Para registrar este procedimiento almacenado en Informix, copie el siguiente script en un archivo (por ejemplo, test1.sql)

DROP SPECIFIC PROCEDURE dbSwapParms;
CREATE PROCEDURE dbSwapParms
  (       inParm     CHAR(20),
   OUT    outParm    CHAR(20),
   INOUT  inoutParm  CHAR(20))

   SPECIFIC dbSwapParms

    LET outParm   = inoutParm;
    LET inoutParm = inParm;
END PROCEDURE; 
Ahora ejecute el archivo:

En el entorno de shell del servidor Informix, escriba:

dbaccess <NombreBasedatos> <vía acceso totalmente calificada/test1.sql>
Al ejecutarse este código, puede esperarse el siguiente resultado:
  • El valor del parámetro IN no cambia (y no puede hacerlo, por definición).
  • El valor del parámetro OUT pasa a ser "World".
  • El valor del parámetro INOUT pasa a ser "Hello".

Se aplican las siguientes limitaciones a los procedimientos almacenados de Informix:

Ejemplo 7 de rutina de base de datos

Este ejemplo muestra cómo llamar a un procedimiento almacenado que devuelve dos conjuntos de resultados, además de un parámetro de salida:

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

Utilice el siguiente ESQL para invocar myProc1:

/* utilizando una referencia de campo */
CALL myProc1(intVar1, intVar2, Environment.RetVal[], OutputRoot.XMLNS.A[])
/* utilizando una variable de referencia */
CALL myProc1(intVar1, intVar2, myReferenceVariable.RetVal[], myRef2.B[])
Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Comentarios

Copyright IBM Corporation 1999, 2014Copyright IBM Corporation 1999, 2014.

        
        Última actualización:
        
        Última actualización: 2015-02-28 16:59:54


Tema de referenciaTema de referencia | Versión 8.0.0.5 | ak04970_