Procedimentos armazenados usados em instruções chamáveis e preparadas

Explore a execução de Procedimentos Armazenados usando uma instrução chamável com o driver JDBC Informix

Para melhorar o desempenho de um banco de dados relacional, é comum usar procedimentos armazenados, que nada mais são que funções definidas pelo usuário, contendo uma série de instruções SQL e armazenadas em um banco de dados. Neste artigo, mostraremos como acessar um Procedimento Armazenado por meio de instruções chamáveis com o driver JDBC Informix®. CallableStatement de JDBC estende PreparedStatement e envia ao servidor uma solicitação para executar um Procedimento Armazenado para operações complexas, como retornar valores ou usar parâmetros de Procedimento Armazenado de entrada e saída.

Babita Sonavane, Software Developer, IBM

Babita SonavaneBabita Sonavane é desenvolvedora de software no IBM India Lab, em Bangalore. Babita tem mais de cinco anos de experiência em TI. Ela trabalha ativamente na manutenção e desenvolvimento de vários recursos nos drivers JDBC Informix e DB2.



Javier Sagrera, Software Engineer, IBM

Photo of author Javier SagreraJavier Sagrera é engenheiro de software no grupo Common Client Technologies (CCT). Ele passou a fazer parte da equipe Informix em 2000 e tem mais de 10 anos de experiência em desenvolvimento de aplicativos para servidores de bancos de dados e clientes Informix. Trabalhando atualmente no IBM UK Bedfont Lab, em Londres, ele tem conhecimento extenso sobre todas as tecnologias Microsoft® e é considerado especialista mundial em todas as ferramentas de desenvolvimento Informix.



01/Out/2012

Introdução

Em um aplicativo de banco de dados relacional, a principal vantagem de usar procedimentos armazenados em vez de instruções de SQL únicas é que o plano de consultas (ou plano de execução) é gerado quando o procedimento armazenado é criado, e o mesmo plano de consultas é reutilizado a cada execução do procedimento armazenado. Isso economiza uma quantidade considerável de recursos no servidor de banco de dados. Quando criado uma única vez, eles podem ser chamados por qualquer cliente de banco de dados, como aplicativos JDBC, quantas vezes necessário, sem precisar de um novo plano de execução.

A maneira de usar os procedimentos armazenados varia dependendo do servidor de banco de dados. Um sistema de gerenciamento de banco de dados (DBMS), como Informix e DB2®, tem uma sintaxe SQL diferente para a execução de procedimentos armazenados. Isso cria um problema para desenvolvedores de aplicativos quando eles precisam escrever códigos para vários DBMSs. Uma declaração chamável é um método para executar procedimentos armazenados usando a mesma sintaxe SQL em todos os sistemas DBMS.


Por que usar procedimentos armazenados?

Imagine que temos um aplicativo JDBC que precisa repetir, de forma eficiente, uma sequência de tarefas várias vezes. Uma opção é usar um método Java™, mas quantas vezes queremos fazer comunicação cliente/servidor para enviar e receber dados? O servidor de banco de dados prepara e gera um plano de consulta para cada instrução SQL enviada pelo aplicativo, o que consome tempo de CPU. Ao levar o desempenho em consideração, o uso de métodos Java simples com instruções SQL únicas pode ser uma má ideia.

Que tal usar um procedimento armazenado, que é uma tarefa realizada apenas uma vez? Crie uma única chamada SQL, que pode ser chamada a partir do aplicativo JDBC usando o objeto CallableStatement, que age como responsável pela chamada para o procedimento armazenado no servidor. A maior parte da lógica de negócios irá residir no procedimento armazenado. Isso ajuda a simplificar o código do cliente e acelera a execução, pois as instruções SQL incluídas no procedimento armazenado foram preparadas e otimizadas quando o procedimento foi criado.


Chamando procedimentos armazenados em aplicativos JDBC

O driver JDBC Informix fornece os métodos Statement, PreparedStatement e CallableStatement, que podem ser usados para executar procedimentos armazenados. O método a ser usado depende das características do procedimento armazenado. Por exemplo, se o procedimento retorna um único valor, você deve usar um objeto JDBC Statement. A tabela a seguir contém algumas diretrizes para escolher o método a ser usado para cada tipo de procedimento armazenado.

Tablela 1. A Tabela mostra qual método JDBC usar com base no respectivo tipo de procedimento armazenado
Tipo de procedimento armazenadoMétodo JDBC
O procedimento armazenado não requer parâmetros IN ou OUT.Use um objeto Statement
Procedimento armazenado com parâmetro IN.Use um objeto PreparedStatement
Procedimento armazenado com parâmetros IN e OUT.Use um objeto CallableStatement

Daremos alguns exemplos da execução de um procedimento armazenado usando métodos JDBC Informix nos seguintes casos:

  • Uso de Statement sem parâmetros
  • Uso de PreparedStatement com parâmetros de entrada
  • Uso de CallableStatement com parâmetros de saída
  • Parâmetros nomeados em CallableStatement
  • Procedimentos armazenados sobrecarregados

Cada tópico mencionado acima terá os seguintes detalhes:

  • Sintaxe usada para chamar o procedimento armazenado a partir do procedimento do driver JDBC Informix
  • O esquema do procedimento armazenado no banco de dados
  • Programa do driver JDBC de amostra com a saída

Uso do objeto Statement sem parâmetros

A Listagem 1 mostra a sintaxe usada para executar um procedimento armazenado sem parâmetros IN ou OUT.

Lista 1. Sintaxe usada para executar um procedimento armazenado sem parâmetros IN ou OUT.
{call procedure-name}

Não é necessário usar o objeto CallableStatement com esse tipo de procedimento armazenado. É possível usar uma instrução JDBC simples. O código na Listagem 2 mostra a definição do procedimento armazenado usando SQL Informix. O exemplo a seguir, GetCustName, retorna um único conjunto de resultados que contém uma coluna de dados, uma combinação do nome e sobrenome dos cinco primeiros contatos na tabela de clientes.

Lista 2. Definição do procedimento armazenado usando o objeto Statement sem parâmetros
CREATE PROCEDURE GETCUSTNAME() RETURNING LVARCHAR AS NAME;
DEFINE W_NAME LVARCHAR;
FOREACH
SELECT FIRST 5 FNAME  ||  ' ' || LNAME INTO W_NAME
FROM CUSTOMER
RETURN W_NAME WITH RESUME;
END FOREACH;
END PROCEDURE;

OBSERVAÇÃO: Esta amostra de procedimento armazenado (e todas as outras deste artigo) usa as tabelas criadas no banco de dados de demonstração stores_demo, que é uma opção selecionável durante a instalação do Informix IDS.

A Listagem 3 mostra o código Java JDBC para execução do procedimento armazenado.

Lista 3. Código JDBC usando o objeto Statement sem parâmetros
public static void executeStoredprocNoParams(Connection con) {
        try {
            Statement stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery("{call GETCUSTNAME}");
            while (rs.next()) {
            System.out.println(rs.getString("Name"));
            }
            rs.close();
            stmt.close();
            }
        catch (Exception e) {
            e.printStackTrace();
            }
}

Como o procedimento armazenado retorna um conjunto de resultados, é necessário usar o método Statement.executeQuery() e buscar nos resultados usando ResultSet.next(). A Listagem 4 mostra a saída do seguinte programa.

Lista 4. Saída do programa da Listagem 3
$java sample_Stored procedure_1
                
Ludwig          Pauli
Carole          Sadler
Philip          Currie
Anthony         Higgins
Raymond         Vector
George          Watson
                
$

Uso de PreparedStatement com parâmetros de entrada

Esse é o mais comum dos procedimentos armazenados. Um procedimento armazenado requer que parâmetros lhe passem dados para processamento interno. Devemos usar um PreparedStatement para lidar com esse tipo de procedimento armazenado. A sintaxe é exibida na Listagem 5.

Lista 5. Sintaxe usada para execução de procedimentos armazenados usando instruções preparadas com parâmetros de entrada
{call procedure-name(?,?,...)}

Embora seja possível usar a sintaxe SQL do Informix para executar o procedimento armazenado (por exemplo, executar o procedimento procedure_name(?,?)), recomendamos continuar com a sintaxe da sequência de escape SQL.

Os pontos de interrogação (?) correspondem a cada um dos parâmetros de entrada exigidos pelo procedimento armazenado. Eles agem como marcador para os valores passados para o procedimento armazenado.

Para especificar um valor para o parâmetro, é possível usar um dos métodos setter na classe IfxPreparedStatement (p.ex., pstmt.setInt()). O método setter que é possível usar é determinado pelo tipo de dados do parâmetro IN. Além do valor do parâmetro, o método setter obtém a posição do parâmetro na instrução SQL.

Lista 6. Exemplo mostrando um procedimento armazenado com uma assinatura
UPDMANU(INT MN_CODE, CHAR(10) MN_NAME, DATE MN_UPD);
Lista 7. Fragmento de código Java deve ser usado no caso do exemplo mostrado na Listagem 6
pstmt = con.prepareStatement("{call updmanu(?,?,?)}");
pstmt.setInt(1, manu_id);
pstmt.setString(2, manu_code);
pstmt.setDate(3, manu_date);

A Listagem 8 mostra o seguinte procedimento armazenado para demonstrar como usar os parâmetros IN.

Lista 8. Exemplo de procedimento armazenado demonstrando como usar os parâmetros IN.
CREATE PROCEDURE GETORDERS(CUS_ID INT) RETURNING INT AS ORDER_NUM, 
DATE AS ORDER_DATE, LVARCHAR AS SHINSTRUC;
DEFINE W_ORDERN INT;
DEFINE W_ORDERD DATE;
DEFINE W_SHIP LVARCHAR;  
    FOREACH
        SELECT ORDER_NUM,ORDER_DATE,SHIP_INSTRUCT 
        INTO W_ORDERN,W_ORDERD,W_SHIP
    FROM ORDERS WHERE ORDERS.CUSTOMER_NUM=CUS_ID
        RETURN W_ORDERN,W_ORDERD,W_SHIP WITH RESUME;
    END FOREACH;
END PROCEDURE;

Esse procedimento armazenado aceita um único parâmetro de entrada, chamado CUS_ID, que é um valor de número inteiro, e retorna uma lista dos pedidos para esse customer_id. O código Java para chamar esse procedimento armazenado está na Listagem 9.

Lista 9. Código Java para execução de procedimento armazenado usando instruções preparadas com parâmetros de entrada
public static void executeSprocInParams(Connection con, int c_id) {
    try {
        PreparedStatement pstmt = con.prepareStatement("{call getorders(?)}");
        pstmt.setInt(1, c_id);
        ResultSet rs = pstmt.executeQuery();                
        while (rs.next()) {
            System.out.println("Order Number\t: "+rs.getString("order_num"));
            System.out.println("Order Date\t: "+rs.getString("order_date"));
            System.out.println("Instructions\t: "+rs.getString("shinstruc"));
            System.out.println();
            }
        rs.close();
        pstmt.close();
        }
    catch (Exception e) {
        e.printStackTrace();
    }
}

Executando o método executeSprocInParams(), podemos ver a saída, como mostra a Listagem 10.

Lista 10. Saída do programa mostrado na Listagem 9
$java sample_Stored procedure_2
Order Number    : 1001
Order Date      : 2008-05-20
Instructions    : express
                
Order Number    : 1003
Order Date      : 2008-05-22
Instructions    : express
                
Order Number    : 1011
Order Date      : 2008-06-18
Instructions    : express
                
Order Number    : 1013
Order Date      : 2008-06-22
Instructions    : express
$

Uso de CallableStatement com parâmetro de saída

Se o procedimento armazenado exigir o uso de parâmetros IN ou OUT, é necessário usar um JDBC CallableStatement para lidar com os parâmetros. Apenas a classe IfxCallableStatement (que é uma extensão de CallableStatement de Java) pode lidar com parâmetros IN e OUT.

Em seguida, iremos demonstrar como chamar um procedimento armazenado que retorna um ou mais parâmetros OUT. Esses são os parâmetros que o procedimento armazenado usa para retornar dados para o aplicativo de chamada como valores individuais, e não um conjunto de resultados, como vimos antes. A sintaxe SQL usada para procedimentos armazenados IN/OUT é semelhante ao que mostramos antes na Lista 5.

Lista 11. Sintaxe usada para execução de procedimentos armazenados usando instruções chamáveis com parâmetros de saída
{call procedure-name(?,?,...)}

É necessário seguir a ordem correta para o parâmetro (IN e OUT). Os valores dos parâmetros OUT devem ser registrados usando o método registerOutParameter() da classe CallableStatement. Cada parâmetro OUT deve ser especificado na ordem correta. Assim como com o parâmetro IN, o primeiro parâmetro desse método é o ordinal (ou posição) do parâmetro —cstmt.registerOutParameter(2, Types.INTEGER);, por exemplo.

O valor especificado para o parâmetro OUT no método registerOutParameter deve ser um dos tipos de dados JDBC Informix contidos em java.sql.Types, convertido internamente para um dos tipos de dados IDS nativos.

Para este exemplo, usaremos o seguinte procedimento armazenado, que usa a tabela "items" do banco de dados stores_demo, como mostra a Listagem 12.

Lista 12. Procedimento armazenado usado para demonstrar como usar os parâmetros OUT
CREATE PROCEDURE GETTOTAL(ORDER_ID INT, OUT TOTALPRICE MONEY);  
LET TOTALPRICE=(SELECT SUM(TOTAL_PRICE) FROM ITEMS WHERE ORDER_NUM=ORDER_ID);  
END PROCEDURE;

Esse procedimento armazenado retorna um único parâmetro OUT (TotalPrice), que é um número inteiro, baseado no parâmetro IN especificado (Order_ID), que também é um número inteiro. O valor retornado no parâmetro OUT é a soma de todos os itens de um número de pedido específico contidos na tabela de itens.

Lista 13. Código Java para execução de procedimento armazenado usando instruções chamáveis sem parâmetros de saída
public static void executeStoredProcOUTParams(Connection con,int o_id) {
    try {
        CallableStatement cstmt = con.prepareCall("{call GetTotal(?, ?)}");
        cstmt.setInt(1, o_id);
        cstmt.registerOutParameter(2, Types.INTEGER);
        cstmt.execute();
        System.out.println("Total price for order" + o_id +"is $"+cstmt.getInt(2));
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

Parâmetros nomeados em um CallableStatement

No exemplo anterior, usamos a posição para identificar cada um dos parâmetros no procedimento armazenado. É possível identificar os parâmetros por nome, o que torna o código do aplicativo mais limpo e mais fácil de ler.

O exemplo a seguir demonstra como usar parâmetros nomeados em um aplicativo Java. Observe que os nomes de parâmetro correspondem aos nomes de parâmetro na definição do procedimento armazenado.

Lista 14. Como usar parâmetros nomeados em um aplicativo Java
public static void executeStoredProcOUTParams(Connection con,int o_id) {
    try {
    CallableStatement cstmt = con.prepareCall("{call GetTotal(?, ?)}");
    cstmt.setInt("Order_ID", o_id);
    cstmt.registerOutParameter("TotalPrice", Types.INTEGER);
    cstmt.execute();
    System.out.println("Total price for order"+ o_id +"is $"+cstmt.getInt("TotalPrice"));
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

Os parâmetros devem ser indicados por índice ou por nome. Não é possível misturar os dois métodos. Essas duas amostras Java produzem a saída a seguir, mostrando o preço total de um pedido específico:

Lista 15. Saída das duas amostras de Java nas Listagens 13 e 14
$java sample_Stored procedure_3
Total price for order 1002 is $1200
$

OBSERVAÇÃO: Esses exemplos usam o método execute() da classe CallableStatement para executar o procedimento armazenado. Isso é usado porque o procedimento armazenado não retornou um conjunto de resultados. Se retornou, o método executeQuery() deve ser usado, como no exemplo a seguir.

Lista 16. Procedimento armazenado usado para ilustrar quando usar o método executeQuery()
CREATE PROCEDURE GETTOTALBYMANU(CODE CHAR(3),  OUT TOTAL MONEY) 
RETURNING CHAR(3) AS MANU_CODE, CHAR(10) AS MANU_NAME;  
DEFINE W_MANU_CODE CHAR(3);
DEFINE W_MANU_NAME CHAR(10); 
LET TOTAL=(SELECT SUM(TOTAL_PRICE) FROM ITEMS WHERE MANU_CODE=CODE);   
SELECT MANU_CODE,MANU_NAME
  INTO W_MANU_CODE,W_MANU_NAME FROM MANUFACT WHERE MANU_CODE=CODE;
RETURN W_MANU_CODE,W_MANU_NAME;		      
END PROCEDURE;

O método na Listagem 17 usa executeQuery() para chamar o procedimento armazenado GetTotalByManu.

Lista 17. Código Java usado para ilustrar o uso do método executeQuery()
public static void executeStoredProcOUTParamsResulset(Connection con,String manu_id) {
    try {
        CallableStatement cstmt = con.prepareCall("{ call gettotalbymanu(?,?)}");
        cstmt.setString(1, manu_id);	  	  
        cstmt.registerOutParameter(2, Types.CHAR);
        ResultSet rs = cstmt.executeQuery();
        rs.next();		
        System.out.println("Total for manufacturer '"+rs.getString(2).trim()+
        " ("+rs.getString(1)+") ' is $"+cstmt.getInt(2));
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

A saída do programa mostrado na Listagem 17 é mostrada na Listagem 18.

Lista 18. Saída do programa de exemplo Java da Listagem 17
$java sample_Stored procedure_4
Total for manufacturer 'Hero (HRO)' is $2882
$

OBSERVAÇÃO: Se você não sabe como o procedimento armazenado foi definido, pode usar rotinas de metadados JDBC para obter informações sobre o procedimento, como o nome e o tipo dos parâmetros que ele aceita.

O exemplo a seguir usa o método getProcedureColumns() para obter o nome e o tipo do procedimento gettotalbymanu.

Lista 19. Código Java
public static void executeStoredGetOutParams(Connection con,String procname) {
    try {
        DatabaseMetaData dbmd = con.getMetaData();
        ResultSet rs = dbmd.getProcedureColumns("stores7","",procname.toUpperCase(),null);
        while (rs.next())
        if (rs.getShort("COLUMN_TYPE")==DatabaseMetaData.procedureColumnOut) {
        System.out.println("OUT Parame: "+ rs.getString("COLUMN_NAME"));
        System.out.println("Type: "+rs.getString("DATA_TYPE") );		 
        }	  
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

Outra alternativa possível é verificar se o procedimento armazenado tem parâmetros OUT usando o método CallableStatement.hasOutParameter(). Se tiver sido definido com parâmetros OUT, ele retorna TRUE, como mostra a Listagem 20.

Lista 20. Código Java de amostra
CallableStatement cstmt = con.prepareCall("{ call gettotalbymanu(?,?)}");
if (((IfxCallableStatement) cstmt).hasOutParameter())
System.out.println("Stored procedure has OUT parameters ");
// perform the logic

Chamando procedimentos armazenados com mais de uma assinatura

O servidor de banco de dados Informix suporta procedimentos armazenados sobrecarregados. É possível ter procedimentos armazenados com o mesmo nome mas com parâmetros (ou assinaturas) diferentes, para realizarem operações diferentes com base no parâmetro recebido. Um exemplo básico são os procedimentos mostrados na Lista 21 e Lista 22.

Lista 21. Definição de procedimento armazenado nº 1
CREATE PROCEDURE GETORDERS(CUS_ID INT) RETURNING INT 
AS ORDER_NUM, DATE AS ORDER_DATE, LVARCHAR AS SHINSTRUC;
    DEFINE W_ORDERN INT;
    DEFINE W_ORDERD DATE;
    DEFINE W_SHIP LVARCHAR;  
    FOREACH
        SELECT ORDER_NUM,ORDER_DATE,SHIP_INSTRUCT 
        INTO W_ORDERN,W_ORDERD,W_SHIP
FROM ORDERS WHERE ORDERS.CUSTOMER_NUM=CUS_ID
        RETURN W_ORDERN,W_ORDERD,W_SHIP WITH RESUME;
    END FOREACH;
END PROCEDURE;
Lista 22. Definição de procedimento armazenado nº 2
CREATE PROCEDURE GETORDERS(ORD_DATE DATE) RETURNING INT 
AS ORDER_NUM, DATE AS ORDER_DATE, LVARCHAR AS SHINSTRUC;
    DEFINE W_ORDERN INT;
    DEFINE W_ORDERD DATE;
    DEFINE W_SHIP LVARCHAR;  
    FOREACH
        SELECT ORDER_NUM,ORDER_DATE,SHIP_INSTRUCT 
        INTO W_ORDERN,W_ORDERD,W_SHIP
FROM ORDERS WHERE ORDERS.ORDER_DATE=ORD_DATE
        RETURN W_ORDERN,W_ORDERD,W_SHIP WITH RESUME;
    END FOREACH;
END PROCEDURE;

Ambos têm o mesmo nome (GETORDERS), mas o primeiro usa um parâmetro INT para obter os pedidos de um cliente específico, e o segundo tem um parâmetro DATE para retornar os pedidos para uma data específica, como mostra a Listagem 23.

Lista 23. Exemplo para mais de uma assinatura
CREATE PROCEDURE GETORDERS(CUS_ID INT) RETURNING INT 
AS ORDER_NUM, DATE AS ORDER_DATE, LVARCHAR AS SHINSTRUC;
                
CREATE PROCEDURE GETORDERS(ORD_DATE DATE) RETURNING INT 
AS ORDER_NUM, DATE AS ORDER_DATE, LVARCHAR AS SHINSTRUC;

Para executar esses procedimentos armazenados em um aplicativo JDBC, é necessário fornecer o tipo de parâmetro na sintaxe SQL para que o mecanismo Informix saiba qual procedimento deve ser executado. Use o prefixo ::datatype no marcador, como mostra a Listagem 24.

Lista 24. Exemplos de marcador
{call getorders(?::INT)}
{call getorders(?::DATE)}

A Listagem 25 mostra como executar o procedimento GETORDERS(DATE).

Lista 25. Código Java para demonstrar como usar procedimentos armazenados com mais de uma assinatura
public static void executeSprocInParams_date(Connection con, String o_date) {
    try {
        PreparedStatement pstmt = con.prepareStatement("{call getorders(?::DATE)}");
        pstmt.setString(1, o_date);
        ResultSet rs = pstmt.executeQuery();
        while (rs.next()) {
            System.out.println("Order Number\t: "+rs.getString("order_num"));
            System.out.println("Order Date\t: "+rs.getString("order_date"));
            System.out.println("Instructions\t: "+rs.getString("shinstruc"));
            System.out.println();
        }
        rs.close();
        pstmt.close();
    }
         catch (Exception e) {
        e.printStackTrace();
    }
}

Conclusão

Este artigo mostrou várias maneiras de acessar procedimentos armazenados simples e complexos a partir de um aplicativo JDBC. Os links para a documentação do servidor e do JDBC na seção Recursos darão assistência para que você explore os exemplos de código e desenvolva procedimentos armazenados eficientes e o aplicativo JDBC equivalente. Tudo o que você aprendeu neste artigo deve ajudá-lo a transferir uma lógica de negócios complexa para procedimentos armazenados e exportá-los para um aplicativo JDBC.

Recursos

Aprender

Obter produtos e tecnologias

  • Crie seu próximo projeto de desenvolvimento com o software de avaliação da IBM, disponível para download diretamente no developerWorks.
  • Agora é possível usar o DB2 gratuitamente. Faça o download do O DB2 Express-C, uma versão gratuita do DB2 Express Edition para a comunidade que oferece os mesmos recursos de dados centrais que o DB2 Express Edition e fornece uma base sólida para desenvolver e implementar aplicativos.

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Information Management
ArticleID=838383
ArticleTitle=Procedimentos armazenados usados em instruções chamáveis e preparadas
publish-date=10012012