WebSphere Message Broker, Versão 8.0.0.5 Sistemas operacionais: AIX, HP-Itanium, Linux, Solaris, Windows, z/OS

Consulte as informações sobre a versão mais recente do produto em IBM Integration Bus, Versão 9.0

Instrução CREATE PROCEDURE

A instrução CREATE PROCEDURE define uma função ou procedimento que pode ser chamado.

Você também pode utilizar a instrução CREATE FUNCTION para definir uma função ou um procedimento que pode ser chamado, também conhecido como rotina.

Cada rotina possui um nome, que deve ser exclusivo no esquema ao qual ela pertence. Os nomes de rotina, portanto, não podem ser sobrecarregados; se o intermediário detectar que um nome de rotina foi sobrecarregado, ele exibirá uma exceção.

Sintaxe

Ler diagrama de sintaxeManter visual do diagrama de sintaxe
>>-CREATE--| RoutineType |--RoutineName------------------------->

>--(--| ParameterList |--)--+----------------+------------------>
                            '-| ReturnType |-'   

>--+--------------+--+---------------+--| RoutineBody |--------><
   '-| Language |-'  '-| ResultSet |-'                    

RoutineType

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

ParameterList

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

Parâmetro

        (1)                                                
|--+-IN-----+--ParameterName--+-+----------+--DataType-+-------->
   +-OUT----+                 | '-CONSTANT-'           |   
   '-INOUT--'                 |           (2)          |   
                              +-NAMESPACE--------------+   
                              '-NAME-------------------'   

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

ReturnType

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

Language

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

ResultSet

|--DYNAMIC RESULT SETS--integer---------------------------------|

RoutineBody

|--+-Statement-------------------------------------------------------+--|
   '-EXTERNAL--NAME--ExternalRoutineName--+------------------------+-'   
                                          +-.NetTypeInfo-----------+     
                                          '-JavaClassLoaderService-'     

.NetTypeInfo

|--ASSEMBLY--AssemblyName--------------------------------------->

   .----------------------------------------.   
   V  (4)                                   |   
>--------+--------------------------------+-+-------------------|
         +-APPDOMAIN--DomainName----------+     
         +-VERSION--Versão----------------+     
         +-CULTURE--Cultura---------------+     
         '-PUBLICKEYTOKEN--PublicKeyToken-'     

JavaClassLoaderService

|--CLASSLOADER--ClassLoaderConfigurableServiceName--------------|

Notas:
  1. Se o tipo de rotina for FUNCTION, o indicador de direção (IN, OUT ou INOUT) será opcional para cada parâmetro. Entretanto, para fins de documentação, é uma boa prática de programação especificar um indicador de direção para todas as novas rotinas; se você não especificar a direção, um valor padrão igual a IN será utilizado.
  2. Quando a cláusula NAMESPACE ou NAME é utilizada, seu valor é implicitamente CONSTANT e do tipo CHARACTER. Para obter informações sobre a utilização de variáveis CONSTANT, consulte Instrução DECLARE.
  3. Se o tipo de rotina for FUNCTION, não é possível especificar um LANGUAGE de DATABASE.
  4. Cada um pode ser especificado apenas uma vez.

Direções de Parâmetros

Os parâmetros que são transmitidos para rotinas sempre possuem uma direção associada a eles, que é um dos seguintes tipos:
IN
O valor do parâmetro não pode ser alterado pela rotina. Um valor NULL para o parâmetro é permitido e pode ser transmitido para a rotina.
OUT
Quando ele é recebido pela rotina chamada, o parâmetro que é transmitido para a rotina sempre possui um valor NULL do tipo de dados correto. Esse valor é configurado independentemente de seu valor antes da chamada da rotina. A rotina tem permissão para alterar o valor do parâmetro.
INOUT
INOUT é um parâmetro IN e OUT. Ele transmite um valor para a rotina e o valor que é transmitido pode ser alterado pela rotina. É permitido um valor NULL para o parâmetro e ele pode ser transmitido para e a partir da rotina.
NULLABLE
Essa cláusula opcional indica que o valor do parâmetro tem permissão para conter um valor NULL. NULL é a cláusula padrão se essa cláusula for omitida, a menos que a cláusula NOT NULL seja especificada.
NOT NULL
Essa cláusula opcional indica que o valor do parâmetro não pode conter um valor NULL. Se um parâmetro estiver marcado como NOT NULL e um valor NULL for transmitido na chamada, será lançada uma exceção. Nota: Atualmente, essa cláusula pode ser usada apenas com LANGUAGE CLR ou LANGUAGE .NET.

Se o tipo de rotina for FUNCTION, o indicador de direção (IN, OUT, INOUT) será opcional para cada parâmetro. No entanto, é uma boa prática de programação especificar um indicador de direção para todas as novas rotinas de qualquer tipo para finalidades de documentação.

As variáveis ESQL que são declaradas como CONSTANT (ou referências a variáveis declaradas como CONSTANT) não têm permissão para ter a direção OUT ou INOUT.

Rotinas ESQL

As rotinas ESQL são escritas em ESQL e possuem uma cláusula LANGUAGE de ESQL. O corpo de uma rotina ESQL é geralmente uma instrução composta da forma BEGIN … END, que contém várias instruções para processar os parâmetros que são transmitidos para a rotina.

Exemplo 1 de ESQL

O exemplo a seguir mostra o mesmo procedimento que no Exemplo 1 de Rotina de Banco de Dados, mas ele é implementado como uma rotina ESQL e não como um procedimento armazenado. A sintaxe CALL e os resultados dessa rotina são os mesmos encontrados em:
CREATE PROCEDURE swapParms (
  IN parm1 CHARACTER,
  OUT parm2  CHARACTER,
  INOUT parm3 CHARACTER )
BEGIN
   SET parm2 = parm3;
   SET parm3 = parm1;
 END; 

Exemplo 2 de ESQL

Este procedimento de exemplo mostra o uso recursivo de uma rotina ESQL. Ele analisa uma árvore, visitando todos os locais no ponto inicial especificado, e abaixo dele, e relata o que foi localizado:

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;

Ao receber a seguinte mensagem de entrada:

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

o procedimento produz a seguinte saída, que foi formatada 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

Rotinas .NET

Uma rotina .NET é implementada como um método .NET e possui uma cláusula LANGUAGE de .NET ou CLR. Para rotinas .NET, o ExternalRoutineName deve conter o nome da classe e o nome do método .NET a ser chamado. Especifique o ExternalRoutineName como neste exemplo:

>>--"-- className---.---methodName--"--------------><
Em que className identifica a classe que contém o método e methodName identifica o método a ser chamado. Se a classe fizer parte de um Namespace ou for uma classe aninhada, a parte do identificador de classes deverá incluir todos os nomes de Namespace e de classes aninhadas; por exemplo, "IBM.Broker.test.MyOuterClass.MyNestedClass.MyMethod"

Para localizar a classe .NET, o broker procura o GAC e o local de base AppDomain do conjunto especificado.

Qualquer método .NET que você queira chamar deverá ter um método estático público. Além disso, todos os parâmetros devem estar listados nas Tabelas de Mapeamento de Tipos de Dados ESQL a .NET. Além disso, se o método tiver um tipo de retorno, o tipo de retorno deverá estar listado na tabela de mapeamento do tipo de dados IN.

A assinatura de métodos .NET deve corresponder à declaração das rotinas ESQL do método. Você também deve observar as seguintes regras:
  • Assegure-se de que o nome do método .NET, incluindo o nome da classe e quaisquer qualificadores Namespace, correspondam aos procedimentos de ESQL EXTERNAL NAME.
  • Se o método .NET não tiver um tipo de retorno, não coloque uma cláusula RETURNS na definição de rotinas de ESQL. Por outro lado, se o método .NET não tiver um tipo de retorno, você deverá colocar uma cláusula RETURNS na definição de rotinas de ESQL.
  • Assegure-se de que cada tipo e direção dos parâmetros correspondam à declaração de ESQL, de acordo com as regras listadas nas Tabelas de Mapeamento de Tipos de Dados ESQL a .NET.
  • Verifique se o tipo de retorno dos métodos corresponde ao tipo de dados da cláusula RETURNS.
  • Coloque EXTERNAL NAME entre aspas porque ele deve conter pelo menos "Class.Method".
  • Se desejar chamar um método .NET sobrecarregado, deverá criar uma definição ESQL separada para cada método sobrecarregado e fornecer a cada definição ESQL um nome de rotina exclusivo.
Informações do Tipo .NET
A cláusula na seção Informações do Tipo .NET se aplica apenas às rotinas LANGUAGE .NET.
ASSEMBLY
O ASSEMBLY indica o conjunto .NET no qual reside o método a ser chamado. Se o conjunto residir no GAC, ele poderá ser simplesmente o nome do conjunto (por exemplo, “MyAssembly”). Entretanto, se o conjunto não estiver no GAC, ele precisará conter o caminho completo para o conjunto.
APPDOMAIN
Esse parâmetro fornece o nome do APPDOMAIN no qual carregar o conjunto e executar o método. Se essa cláusula for omitida, o APPDOMAIN será configurado com o nome do aplicativo ao qual o fluxo pertence. Se o fluxo não pertencer a um aplicativo, o APPDOMAIN será configurado com o nome do fluxo de mensagens.
VERSION
Fornece a versão exata do conjunto a ser carregado. Se a versão for omitida, a primeira versão encontrada do conjunto denominado será usada.
CULTURE
Fornece a capacidade de especificar uma cultura exata para o conjunto. O padrão é usar a cultura “neutra”.
PUBLICKEYTOKEN
Se o conjunto a ser carregado residir no GAC, seu token de chave pública precisará ser fornecido. Entretanto, se o conjunto não residir no GAC, essa cláusula será opcional. Ao procurar por um conjunto, a ordem de procura será como a definida pelo .NET Framework; os detalhes completos são listados no MSDN. Entretanto, os estados da versão são abreviados; se o nome do conjunto não estiver completo, a base do AppDomain será usada. Se o nome do conjunto estiver completo, (ou seja, a versão e o token de chave pública tiverem sido especificados), o GAC será procurado antes da pasta base de Domínios do App.

Exemplo 1 da Rotina .NET

Define um procedimento que representa um Método .NET que retorna um System:String com três parâmetros de direções 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";
O seguinte ESQL pode ser usado para chamar Swap.
CALL Swap( intVar1, intVar2, intVar3 ) INTO ReturnVar;
-- or
SET ReturnVar = Swap ( intVar1, intVar2, intVar3);

Exemplo 2 da Rotina .NET

Define um procedimento que representa um Método .NET que não tem valor de retorno com três parâmetros Nullable de direções 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";
O seguinte ESQL deve ser usado para chamar SwapNullable.
CALL SwapNullable(intVar1, intVar2, intVar3);

Código de exemplo para várias linguagens .NET que fornecem métodos para os dois exemplos

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;
  }
}

Rotinas Java

Uma rotina Java™ é implementada como um método Java e possui uma cláusula LANGUAGE de JAVA. Para rotinas Java, ExternalRoutineName deve conter o nome da classe e o nome do método do método Java a ser chamado. Especifique o ExternalRoutineName como no seguinte exemplo:
>>--"-- className---.---methodName--"--------------><
em que className identifica a classe que contém o método e methodName identifica o método a ser chamado. Se a classe fizer parte de um pacote, o identifador de classe deverá incluir o prefixo completo do pacote; por exemplo, "com.ibm.broker.test.MyClass.myMethod"

Para localizar a classe Java, o intermediário utiliza o método de procura descrito em Implementando Classes Java.

Qualquer método Java que você deseja chamar deve ter a seguinte assinatura básica:
public static <return-type> <method-name> (< 0 - N parameters>)

Em que <return-type> deve estar na lista de tipos de dados IN Java na tabela em Mapeamento de Tipo de Dados ESQL para Java (excluindo o tipo REFERENCE, que não é permitido como um valor de retorno) ou o tipo de dados void Java. Os tipos de dados do parâmetro também devem estar na tabela Mapeamento de Tipo de Dados ESQL para Java. Além disso, o método Java não pode ter a cláusula exception throws em sua assinatura.

A assinatura de métodos Java deve corresponder à declaração das rotinas ESQL do método. Você também deve observar as seguintes regras:
  • Assegure-se de que o nome do método Java, incluindo o nome da classe e quaisquer qualificadores do pacote, corresponda aos procedimentos de EXTERNAL NAME.
  • Se o tipo de retorno Java for void, não coloque uma cláusula RETURNS na definição de rotina ESQL. Por outro lado, se o tipo de retorno Java não for void, você deverá colocar uma cláusula RETURNS na definição de rotinas ESQL.
  • Assegure-se de que cada tipo e direção dos parâmetros correspondam à declaração ESQL, de acordo com as regras listadas na tabela em Mapeamento de Tipo de Dados ESQL para Java.
  • Verifique se o tipo de retorno dos métodos corresponde ao tipo de dados da cláusula RETURNS.
  • Coloque EXTERNAL NAME entre aspas porque ele deve conter pelo menos "class.method".
  • Se desejar chamar um método Java sobrecarregado, será necessário criar uma definição ESQL separada para cada método sobrecarregado e fornecer a cada definição ESQL um nome de rotina exclusivo.

A cláusula na seção JavaClassLoader aplica-se somente a rotinas de LANGUAGE JAVA. A cláusula CLASSLOADER é opcional; se você não especificar essa cláusula, a classe Java será carregada pelo carregador de classe EGShared. Para obter informações adicionais, consulte o Carregamento de Classe do Nó JavaCompute e o Serviço Configurável JavaClassLoader.

É possível usar a API do nó definido pelo usuário Java em seu método Java, se você observar as restrições documentadas em Restrições com Rotinas Java. Para obter informações adicionais sobre como utilizar a API Java, consulte Compilando um Nó Java Definido pelo Usuário.

Exemplo de Rotina Java 1

Esta rotina contém três parâmetros de diversas direções e retorna um inteiro, que é mapeado para um 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";

É possível utilizar o seguinte ESQL para chamar myProc1:

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

Exemplo de Rotina Java 2

Esta rotina contém três parâmetros de diversas direções e possui um 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";

Você deve utilizar o seguinte ESQL para chamar myProc2:

CALL myProc2(intVar1, intVar2, intVar3);

A classe Java a seguir fornece um método para cada um dos exemplos Java precedentes:

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

 /*  Quando qualquer um desses métodos é chamado:
    P1 pode ou não ser NULL (dependendo do valor de intVar1).
    P2[0] é sempre NULL (qualquer que seja o valor de intVar2).
    P3[0] pode ou não ser NULL (dependendo do valor de intVar3).  
    Isso é igual às rotinas ESQL LANGUAGE. 
    Quando esses métodos retornam:
         intVar1 é inalterado
         intVar2 pode ainda ser NULL ou talvez tenha sido alterado
         intVar3 talvez contenha o mesmo valor ou talvez tenha sido alterado.
     Isso é igual às rotinas ESQL LANGUAGE.
     
    Quando myMethod1 retorna: intReturnVar3 é NULL (se o
    método retornar NULL) ou contém o valor retornado pelo 
    método.
 */
}

Exemplo 3 de Rotina Java

O exemplo a seguir tem uma cláusula LANGUAGE de JAVA e especifica um EXTERNAL NAME para um método Java denominado myMethod1 in class com.ibm.broker.test.MyClass. Também especifica um serviço configurável JavaClassLoader denominado myClassLoader a ser usado para carregar a classe 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";

Mapeamento de Tipo de Dados ESQL para Java

A tabela a seguir resume os mapeamentos de ESQL para Java.
Notas:
  • Apenas os wrappers escalares Java são transmitidos para Java.
  • Os tipos escalares ESQL são mapeados para tipos de dados Java como wrappers de objeto, ou matrizes de wrappers de objeto, dependendo da direção do parâmetro de procedimento. Cada matriz de wrapper contém exatamente um elemento.
  • Os wrappers de objeto escalares são utilizados para permitir que valores NULL sejam transmitidos para e a partir de métodos Java.
Tipos de Dados ESQL1 Tipos de Dados IN Java Tipos de Dados INOUT e OUT Java
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 Não Suportado Não Suportado
BOOLEAN java.lang.Boolean java.lang.Boolean[]
REFERENCE (para uma árvore de mensagens) 3 4 5 6 com.ibm.broker.plugin.MbElement com.ibm.broker.plugin.MbElement[] (Suportado para INOUT. Não suportado para OUT)
ROW Não Suportado Não Suportado
LIST Não Suportado Não Suportado
  1. As variáveis que são declaradas como CONSTANT (ou referências a variáveis que são declaradas CONSTANT) não têm permissão para terem a direção INOUT ou OUT.
  2. O fuso horário configurado na variável Java não é importante; você obtém o fuso horário necessário na ESQL de saída.
  3. O parâmetro de referência não pode ser NULL quando transmitido para um método Java.
  4. A referência não pode ter a direção OUT quando transmitida para um método Java.
  5. Se um MbElement for retornado de Java para ESQL como um parâmetro INOUT, ele deverá apontar para um local na mesma árvore de mensagens apontada pelo MbElement que foi transmitido para o método Java chamado.

    Por exemplo, se uma referência ESQL a OutputRoot.XML.Test for transmitida para um método Java como um MbElement INOUT, mas um MbElement diferente for retornado a ESQL quando a chamada for retornada, o elemento diferente também deverá apontar para algum lugar na árvore OutputRoot.

  6. Um MbElement não pode ser retornado de um método Java com a cláusula RETURNS, porque nenhuma rotina ESQL pode retornar uma referência. No entanto, um MbElement pode ser retornado como um parâmetro de direção INOUT sujeito às condições descritas no ponto 5.

Uma REFERÊNCIA a uma variável escalar pode ser utilizada na CHAMADA de um método Java, desde que o tipo de dados da variável ao qual a referência se refere corresponda ao tipo de dados correspondente na assinatura de programa Java.

Restrições com Rotinas Java

As restrições a seguir se aplicam a rotinas Java chamadas a partir de ESQL:
  • O método Java deve ser thread-safe (reentrante).
  • As conexões com o banco de dados devem ser JDBC tipo 2 ou tipo 4. Além disso, as operações do banco de dados não fazem parte de uma transação do intermediário e, portanto, não podem ser controladas por um coordenador de recursos externo (como é o caso em um ambiente XA).
  • A API do nó definido pelo usuário Java deve ser utilizada apenas pelo mesmo encadeamento que chamou o método Java.

    É possível criar encadeamentos em seu método. No entanto, os encadeamentos criados não devem utilizar APIs Java e é necessário retornar o controle ao intermediário.

    Todas as restrições que se aplicam ao uso da API Java também se aplicam a métodos Java chamados a partir de ESQL.

  • Os métodos Java chamados a partir de ESQL não devem utilizar a classe MbNode. Portanto, eles não podem criar objetos do tipo MbNode ou chamar qualquer um dos métodos em um objeto MbNode existente.
  • O trabalho do WebSphere MQ ou do JMS feito dentro de um método Java que é chamado a partir de ESQL deve ser feito de acordo com as diretrizes para desempenhar o trabalho do WebSphere MQ e JMS em um nó definido pelo usuário. Consulte Planejando Nós de Entrada Definidos pelo Usuário.

Implementando Classes Java

É possível implementar suas classes Java para um broker em um arquivo Java Archive (JAR), usando um dos dois métodos a seguir:
  1. Incluir o arquivo JAR no arquivo BAR (broker archive)

    O método mais eficiente e flexível de implementação no intermediário é incluir seu arquivo JAR no arquivo BAR. Isso pode ser feito manualmente ou automaticamente utilizando o WebSphere Message Broker Toolkit.

    Se a classe WebSphere Message Broker Toolkit finds the correct Java dentro de um projeto Java de referência for aberto no espaço de trabalho, ele compilará automaticamente a classeJava em um arquivo JAR e o incluirá ao arquivo BAR. Este procedimento é o mesmo procedimento seguido para implementar um nó JavaCompute em um JAR, conforme descrito em Carregamento de Classe de Nó Definido pelo Usuário.

    Ao implementar um arquivo JAR do WebSphere Message Broker Toolkit, o fluxo que foi reimplementado recarregará o arquivo JAR contido no arquivo BAR.

    Os arquivos também serão recarregados se o fluxo de mensagens que se refere a uma classe Java for parado e reiniciado. Certifique-se de parar e reiniciar (ou reimplementar) todos os fluxos que se referem ao arquivo JAR que você deseja atualizar. Essa ação evita o problema de alguns fluxos serem executados com a versão antiga do arquivo JAR e outros fluxos executados com a nova versão.

    O WebSphere Message Broker Toolkit implementa apenas arquivos JAR; ele não implementa arquivos de classe Java independentes.

  2. Armazenar o arquivo JAR em um dos seguintes locais:
    1. A pasta workpath/shared-classes/ na máquina que executa o intermediário
    2. A variável de ambiente CLASSPATH no computador que executa o intermediário

    Você deve concluir esta ação manualmente; não pode utilizar o WebSphere Message Broker Toolkit.

    Neste método, a reimplementação do fluxo de mensagens não recarrega as classes Java referidas; nem pára e reinicia o fluxo de mensagens. A única maneira de recarregar as classes neste caso é parar e reiniciar o próprio intermediário.

Para ativar o intermediário para localizar uma classe Java, assegure que ele esteja em um dos locais precedentes. Se o intermediário não puder localizar a classe especificada, ele gerará uma exceção.

Embora você tenha as opções mostradas anteriormente ao implementar o arquivo JAR, usar o WebSphere Message Broker Toolkit para implementar o arquivo BAR fornece maior flexibilidade ao reimplementar o arquivo JAR.

Rotinas de Banco de Dados

As rotinas de banco de dados são implementadas como procedimentos armazenados de banco de dados. As rotinas de banco de dados possuem uma cláusula LANGUAGE de DATABASE e devem ter um tipo de rotina de PROCEDURE.

Ao escrever procedimentos armazenados, em linguagens como o C, você deve utilizar indicadores NULL para assegurar que seu procedimento possa processar os dados corretamente.

Embora as definições de banco de dados de um procedimento armazenado variem entre os bancos de dados, o ESQL utilizado para chamá-lo não o faz. Os nomes dados aos parâmetros no ESQL não precisam corresponder aos nomes que recebem no lado do banco de dados. Entretanto, o nome externo da rotina, incluindo qualquer especificação de pacote ou de contêiner, deve corresponder a seu nome definido no banco de dados.

A cláusula DYNAMIC RESULT SETS é permitida apenas para rotinas de banco de dados. Isso será necessário apenas se um procedimento armazenado retornar um ou mais conjuntos de resultados. O parâmetro inteiro para esta cláusula deve ser 0 (zero) ou mais, e especifica o número de conjuntos de resultados a serem retornados.

A cláusula RETURNS opcional será requerida se um procedimento armazenado retornar um único valor escalar.

A cláusula EXTERNAL NAME especifica o nome pelo qual o banco de dados conhece a rotina. Pode ser um nome qualificado ou não qualificado, em que o qualificador é o nome do esquema do banco de dados no qual o procedimento está definido. Se você não fornecer um nome de esquema, o nome do usuário da conexão com o banco de dados será utilizado como o esquema no qual o procedimento será localizado. Se o procedimento necessário não existir neste esquema, será necessário fornecer um nome do esquema explícito, na definição de rotina ou na CALL para a rotina no tempo de execução. Para obter informações adicionais sobre a escolha dinâmica do esquema que contém a rotina, consulte o Instrução CALL. Quando um nome qualificado é utilizado, é necessário colocá-lo entre aspas.

Uma rotina completa geralmente tem o formato:
 EXTERNAL NAME "mySchema.myProc";
Entretanto, se o procedimento pertencer a um pacote Oracle, o pacote será tratado como parte do nome do procedimento. Portanto você deve fornecer um nome de esquema e o nome do pacote, no formato:
EXTERNAL NAME "mySchema.myPackage.myProc";  

Este formato permite que o esquema, mas não o nome do pacote, seja escolhido dinamicamente na instrução CALL.

Se o nome do procedimento contiver curingas SQL (que são o caractere porcentagem (%) e o caractere sublinhado (_)), o nome do procedimento será modificado pelo intermediário para incluir o caractere de escape do banco de dados imediatamente antes de cada caractere curinga. Esta técnica assegura que o banco de dados receba os curingas como caracteres literais. Por exemplo, assumindo que o caractere de escape do banco de dados é uma barra invertida, a seguinte cláusula é modificada pelo intermediário para que "mySchema.Proc\_" seja passado para o banco de dados.
EXTERNAL NAME "mySchema.Proc_";  
Todos os procedimentos externos têm as seguintes restrições:
  • Um procedimento armazenado não pode ser sobrecarregado no lado do banco de dados. Um procedimento armazenado será considerado sobrecarregado se houver mais de um procedimento com o mesmo nome no mesmo esquema do banco de dados. Se o intermediário detectar que um procedimento foi sobrecarregado, ele produz uma exceção.
  • Os parâmetros não podem ser dos tipos de dados ESQL REFERENCE, ROW, LIST ou INTERVAL.
  • Os tipos definidos pelo usuário não podem ser utilizados como parâmetros ou como valores de retorno.
Para rotinas LANGUAGE DATABASE, o ExternalRoutineName não é opcional e contém o nome do esquema, o nome do pacote e o nome do procedimento da rotina a ser chamada. Especifique o ExternalRoutineName como a seguir:
>>--"schemaName---.---packageName---.---procedureName--"--------------><
em que:
  • schemaName é opcional.
  • packageName é opcional e se aplica apenas a origens de dados Oracle. Se você fornecer um packageName, deverá fornecer um schemaName.
  • procedureName não é opcional.

Exemplo 1 de Rotina de Banco de Dados

O exemplo a seguir mostra uma definição ESQL de um procedimento armazenado que retorna um único valor escalar e um parâmetro OUT:

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

Utilize este ESQL para chamar a invocar a rotina myProc1:

/*utilizando a sintaxe de chamada de instrução CALL*/
CALL myProc1(intVar1, intVar2) INTO intReturnVar3;

/*ou utilizando a sintaxe de chamada de função*/
SET intReturnVar3 = myProc1(intVar1, intVar2);

Exemplo 2 de Rotina de Banco de Dados

O código ESQL a seguir demonstra como definir e chamar procedimentos armazenados do DB2:

Definição 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 procedimento armazenado no DB2, copie o seguinte script para um arquivo (por exemplo, test1.sql)

-- Procedimento Armazenado de Exemplos do 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 @
Agora, execute o arquivo a partir do prompt de comandos do DB2:
db2 -td@ -vf test1.sql 
Espere os seguintes resultados da execução desse código:
  • O valor do parâmetro IN não se altera (e não pode, por definição).
  • O valor do parâmetro OUT torna-se "World".
  • O valor do parâmetro INOUT é alterado para "Hello".

Exemplo 3 de Rotina de Banco de Dados

O código ESQL a seguir demonstra como definir e chamar procedimentos armazenados Oracle:

Definição 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 procedimento armazenado com o Oracle, copie o script a seguir em um arquivo (por exemplo, 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; 
/
Agora, execute o arquivo:
sqlplus userID/password  @test1.sql
Espere os seguintes resultados da execução desse código:
  • O valor do parâmetro IN não se altera (e não pode, por definição).
  • O valor do parâmetro OUT torna-se "World".
  • O valor do parâmetro INOUT é alterado para "Hello".

Exemplo 4 de Rotina de Banco de Dados

O código ESQL a seguir demonstra como definir e chamar procedimentos armazenados SQL Server:

Definição 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 esse procedimento armazenado com o Servidor SQL, copie o seguinte script para um arquivo (por exemplo, test1.sql)

-- Procedimento Armazenado de Exemplos do 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 
Agora, execute o arquivo:
isql -UuserID -Ppassword -Sserver -ddatasource -itest1.sql

O SQL Server considera parâmetros OUTPUT de procedimentos armazenados como parâmetros INPUT/OUTPUT. Se você declará-los como parâmetros OUT em seu ESQL, encontrará um erro de incompatibilidade de tipos no tempo de execução. Para evitar essa incompatibilidade, você deve declarar os parâmetros OUTPUT do SQl Server como INOUT em seu ESQL.

Utilize a opção SET NOCOUNT ON, como mostrado no exemplo anterior, com procedimentos armazenados SQL pelas seguintes razões:
  1. Para limitar a quantidade de dados retornados do SQL Server para o intermediário.
  2. Para permitir que conjuntos de resultados sejam retornados corretamente.
Espere os seguintes resultados da execução desse código:
  • O valor do parâmetro IN não se altera (e não pode, por definição).
  • O valor do parâmetro OUT torna-se "World".
  • O valor do parâmetro INOUT é alterado para "Hello".

Exemplo 5 de Rotina de Banco de Dados

O código ESQL a seguir demonstra como definir e chamar procedimentos armazenados Sybase:

Definição 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 procedimento armazenado com Sybase, copie o seguinte script para um arquivo (por exemplo, test1.sql)

-- Procedimento Armazenado de Exemplos 
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 
Agora, execute o arquivo:
isql -U<userID> -P<password> -S<server> -D<datasource> -itest1.sql

O Sybase considera parâmetros OUTPUT de procedimentos armazenados como parâmetros INPUT/OUTPUT. Se declará-los como parâmetros OUT em seu ESQL, encontrará um erro de incompatibilidade de tipos no tempo de execução. Para evitar esta incompatibilidade, declare os parâmetros Sybase OUTPUT como INOUT em seu ESQL.

Espere os seguintes resultados da execução desse código:
  • O valor do parâmetro IN não se altera (e não pode, por definição).
  • O valor do parâmetro OUT torna-se "World".
  • O valor do parâmetro INOUT é alterado para "Hello".

Exemplo 6 de Rotina de Banco de Dados

O código ESQL a seguir demonstra como definir e chamar procedimentos armazenados do Informix:

Definição 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 procedimento armazenado no Informix, copie o seguinte script para um arquivo (por exemplo, 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; 
Agora, execute o arquivo:

A partir do ambiente de shell do servidor Informix, insira:

dbaccess <dataBaseName> <fully qualified path/test1.sql>
Espere os seguintes resultados da execução desse código:
  • O valor do parâmetro IN não se altera (e não pode, por definição).
  • O valor do parâmetro OUT torna-se "World".
  • O valor do parâmetro INOUT é alterado para "Hello".

As seguintes restrições se aplicam aos procedimentos armazenados Informix:

Exemplo 7 de Rotina do Banco de Dados

Este exemplo mostra como chamar um procedimento armazenado que retorna dois conjuntos de resultados, além de um parâmetro de saída:

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

Utilize o ESQL a seguir para chamar myProc1:

/* utilizando uma referência de campo */
CALL myProc1(intVar1, intVar2, Environment.RetVal[], OutputRoot.XMLNS.A[])
/* utilizando uma variável de referência*/
CALL myProc1(intVar1, intVar2, myReferenceVariable.RetVal[], myRef2.B[])
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback

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

        
        Última atualização:
        
        Última atualização: 2015-02-28 18:29:53


Tópico de ReferênciaTópico de Referência | Versão 8.0.0.5 | ak04970_