O autor deste artigo apresenta como chamar os procedimentos armazenados do SQL Server por meio de Java e explica detalhadamente cinco tipos diferentes de armazenamento. Por favor, veja abaixo para detalhes
1. Use um procedimento armazenado sem parâmetros
Ao usar um driver JDBC para chamar um procedimento armazenado sem parâmetros, você deve usar a sequência de escape SQL de chamada. A sintaxe para a sequência de escape de chamada sem parâmetros é a seguinte:
Copie o código do código da seguinte forma:
{nome do procedimento de chamada}
Por exemplo, crie o seguinte procedimento armazenado no banco de dados de exemplo AdventureWorks do SQL Server 2005:
Copie o código do código da seguinte forma:
CRIAR PROCEDIMENTO GetContactFormalNames
COMO
COMEÇAR
SELECIONE OS 10 PRINCIPAIS Título + ' ' + Nome + '' + Sobrenome AS Nome Formal
DE Pessoa.Contato
FIM
Esse procedimento armazenado retorna um único conjunto de resultados que contém uma coluna de dados que consiste no título, nome e sobrenome dos primeiros dez contatos na tabela Person.Contact.
No exemplo a seguir, essa função recebe uma conexão aberta com o banco de dados de exemplo AdventureWorks e, em seguida, o procedimento armazenado GetContactFormalNames é chamado usando o método executeQuery.
Copie o código do código da seguinte forma:
public static void executeSprocNoParams(Conexão con) ...{
tentar...{
Instrução stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("{chamar dbo.GetContactFormalNames}");
enquanto (rs.next()) ...{
System.out.println(rs.getString("NomeFormal"));
}
rs.close();
stmt.close();
}
pegar (Exceção e) ...{
e.printStackTrace();
}
}
2. Use um procedimento armazenado com parâmetros de entrada
Ao usar um driver JDBC para chamar um procedimento armazenado com parâmetros, você deve usar a sequência de escape SQL call em conjunto com o método prepareCall da classe SQLServerConnection. A sintaxe para uma sequência de escape de chamada com um parâmetro IN é a seguinte:
Copie o código do código da seguinte forma:
{nome do procedimento de chamada[([parâmetro][,[parâmetro]]...)]}
Ao construir uma sequência de escape de chamada, use o caractere ? (ponto de interrogação) para especificar o parâmetro IN. Este caractere serve como espaço reservado para o valor do parâmetro a ser passado para o procedimento armazenado. Você pode usar um dos métodos setter da classe SQLServerPreparedStatement para especificar valores para parâmetros. Os métodos setter disponíveis são determinados pelo tipo de dados do parâmetro IN.
Ao passar um valor para um método setter, você deve especificar não apenas o valor real a ser usado no parâmetro, mas também a posição ordinal do parâmetro dentro do procedimento armazenado. Por exemplo, se um procedimento armazenado contiver um único parâmetro IN, seu valor ordinal será 1. Se o procedimento armazenado contiver dois parâmetros, o primeiro valor ordinal será 1 e o segundo valor ordinal será 2.
Como exemplo de como chamar um procedimento armazenado que contém um parâmetro IN, use o procedimento armazenado uspGetEmployeeManagers no banco de dados de exemplo do SQL Server 2005 AdventureWorks. Este procedimento armazenado aceita um único parâmetro de entrada denominado EmployeeID, que é um valor inteiro, e retorna uma lista recursiva de funcionários e seus gerentes com base no EmployeeID especificado. Aqui está o código Java que chama esse procedimento armazenado:
Copie o código do código da seguinte forma:
public static void executeSprocInParams(Conexão con) ...{
tentar...{
PreparedStatement pstmt = con.prepareStatement("{call dbo.uspGetEmployeeManagers(?)}");
pstmt.setInt(1, 50);
ResultSet rs = pstmt.executeQuery();
enquanto (rs.next()) ...{
System.out.println("EMPREGADO:");
System.out.println(rs.getString("Sobrenome") + ", " + rs.getString("Nome"));
System.out.println("GERENTE:");
System.out.println(rs.getString("ManagerLastName") + ", " + rs.getString("ManagerFirstName"));
System.out.println();
}
rs.close();
pstmt.close();
}
pegar (Exceção e) ...{
e.printStackTrace();
}
}
3. Use um procedimento armazenado com parâmetros de saída
Ao chamar esses procedimentos armazenados usando um driver JDBC, você deve usar a sequência de escape SQL de chamada em conjunto com o método prepareCall da classe SQLServerConnection. A sintaxe para uma sequência de escape de chamada com um parâmetro OUT é a seguinte:
Copie o código do código da seguinte forma:
{nome do procedimento de chamada[([parâmetro][,[parâmetro]]...)]}
Ao construir uma sequência de escape de chamada, use o caractere ? (ponto de interrogação) para especificar o parâmetro OUT. Este caractere serve como espaço reservado para o valor do parâmetro a ser retornado deste procedimento armazenado. Para especificar valores para parâmetros OUT, você deve usar o método registerOutParameter da classe SQLServerCallableStatement para especificar o tipo de dados de cada parâmetro antes de executar o procedimento armazenado.
O valor especificado para o parâmetro OUT usando o método registerOutParameter deve ser um dos tipos de dados JDBC contidos em java.sql.Types, que por sua vez é mapeado para um dos tipos de dados nativos do SQL Server. Para obter mais informações sobre os tipos de dados JDBC e SQL Server, consulte Noções básicas sobre tipos de dados do driver JDBC.
Ao passar um valor para o método registerOutParameter para um parâmetro OUT, você não deve apenas especificar o tipo de dados a ser usado para o parâmetro, mas também deve especificar a posição ordinal do parâmetro ou o nome do parâmetro no procedimento armazenado. Por exemplo, se um procedimento armazenado contiver um único parâmetro OUT, seu valor ordinal será 1; se um procedimento armazenado contiver dois parâmetros, o primeiro valor ordinal será 1 e o segundo valor ordinal será 2;
Como exemplo, crie o seguinte procedimento armazenado no banco de dados de exemplo AdventureWorks do SQL Server 2005: Com base no parâmetro IN de número inteiro especificado (employeeID), esse procedimento armazenado também retorna um único parâmetro OUT de número inteiro (managerID). Com base no EmployeeID contido na tabela HumanResources.Employee, o valor retornado no parâmetro OUT é ManagerID.
No exemplo a seguir, essa função recebe uma conexão aberta com o banco de dados de exemplo AdventureWorks e, em seguida, o procedimento armazenado GetImmediateManager é chamado usando o método execute:
Copie o código do código da seguinte forma:
public static void executeStoredProcedure(Conexão con) ...{
tentar...{
CallableStatement cstmt = con.prepareCall("{chamar dbo.GetImmediateManager(?, ?)}");
cstmt.setInt(1, 5);
cstmt.registerOutParameter(2,java.sql.Types.INTEGER);
cstmt.execute();
System.out.println("ID DO GERENTE: " + cstmt.getInt(2));
}
pegar (Exceção e) ...{
e.printStackTrace();
}
}
Este exemplo usa posição ordinal para identificar parâmetros. Alternativamente, o parâmetro pode ser identificado pelo seu nome em vez da sua posição ordinal. O exemplo de código a seguir modifica o exemplo anterior para ilustrar como usar parâmetros nomeados em um aplicativo Java. Observe que esses nomes de parâmetros correspondem aos nomes de parâmetros na definição do procedimento armazenado: 11x16CREATE PROCEDURE GetImmediateManager
Copie o código do código da seguinte forma:
@employeeID INT,
@managerID SAÍDA INT
COMO
COMEÇAR
SELECIONE @managerID = ManagerID
DE Recursos Humanos.Funcionário
ONDE EmployeeID = @employeeID
FIM
Os procedimentos armazenados podem retornar contagens de atualização e vários conjuntos de resultados. O driver JDBC do Microsoft SQL Server 2005 está em conformidade com a especificação JDBC 3.0, que afirma que vários conjuntos de resultados e contagens de atualização devem ser recuperados antes da recuperação dos parâmetros OUT. Ou seja, o aplicativo deve primeiro recuperar todos os objetos ResultSet e atualizar a contagem e, em seguida, usar o método CallableStatement.getter para recuperar os parâmetros OUT. Caso contrário, quando o parâmetro OUT for recuperado, o objeto ResultSet e a contagem de atualizações que ainda não foram recuperados serão perdidos.
4. Use procedimentos armazenados com status de retorno
Ao chamar esse procedimento armazenado usando um driver JDBC, você deve usar a sequência de escape SQL de chamada em conjunto com o método prepareCall da classe SQLServerConnection. A sintaxe para uma sequência de escape de chamada que retorna um parâmetro de status é a seguinte:
Copie o código do código da seguinte forma:
{[?=]nome do procedimento de chamada[([parâmetro][,[parâmetro]]...)]}
Ao construir uma sequência de escape de chamada, use o caractere ? (ponto de interrogação) para especificar o parâmetro de status de retorno. Este caractere serve como espaço reservado para o valor do parâmetro a ser retornado deste procedimento armazenado. Para especificar um valor para um parâmetro de status de retorno, você deve especificar o tipo de dados do parâmetro usando o método registerOutParameter da classe SQLServerCallableStatement antes de executar o procedimento armazenado.
Além disso, ao passar o valor do parâmetro de status de retorno para o método RegisterOutParameter, você deve especificar não apenas o tipo de dados do parâmetro a ser usado, mas também a posição ordinal do parâmetro no procedimento armazenado. A posição ordinal do parâmetro de status de retorno é sempre 1 porque é sempre o primeiro parâmetro quando o procedimento armazenado é chamado. Embora a classe SQLServerCallableStatement suporte o uso do nome do parâmetro para indicar um parâmetro específico, você só pode usar o número da posição ordinal do parâmetro para parâmetros de status de retorno.
Por exemplo, crie o seguinte procedimento armazenado no banco de dados de exemplo AdventureWorks do SQL Server 2005:
Copie o código do código da seguinte forma:
CRIAR PROCEDIMENTO CheckContactCity
(@cityName CHAR(50))
COMO
COMEÇAR
SE ((SELECIONE CONTAGEM(*)
DE Pessoa.Endereço
ONDE Cidade = @cityName) > 1)
RETORNO 1
OUTRO
RETORNAR 0
FIM
O procedimento armazenado retorna um valor de status 1 ou 0, dependendo se a cidade especificada pelo parâmetro cityName pode ser encontrada na tabela Person.Address.
No exemplo a seguir, esta função recebe uma conexão aberta com o banco de dados de amostra AdventureWorks e, em seguida, o procedimento armazenado CheckContactCity é chamado usando o método execute:
Copie o código do código da seguinte forma:
public static void executeStoredProcedure(Conexão con) ...{
tentar...{
CallableStatement cstmt = con.prepareCall("{? = chamar dbo.CheckContactCity(?)}");
cstmt.registerOutParameter(1,java.sql.Types.INTEGER);
cstmt.setString(2, "Atlanta");
cstmt.execute();
System.out.println("STATUS DE RETORNO: " + cstmt.getInt(1));
}
cstmt.close();
pegar (Exceção e) ...{
e.printStackTrace();
}
}
5. Use um procedimento armazenado com uma contagem de atualizações
Depois de usar a classe SQLServerCallableStatement para construir uma chamada para um procedimento armazenado, você poderá usar os métodos execute ou executeUpdate para chamar o procedimento armazenado. O método executeUpdate retorna um valor int contendo o número de linhas afetadas por este procedimento armazenado, mas o método execute não retorna esse valor. Se você usar o método execute e quiser obter uma contagem do número de linhas afetadas, poderá chamar o método getUpdateCount após executar o procedimento armazenado.
Por exemplo, crie as seguintes tabelas e procedimentos armazenados no banco de dados de exemplo AdventureWorks do SQL Server 2005:
Copie o código do código da seguinte forma:
CRIAR TABELA TestTable
(Col1 int IDENTIDADE,
Col2varchar(50),
Col3int);
CRIAR PROCEDIMENTO UpdateTestTable
@Col2varchar(50),
@Col3int
COMO
COMEÇAR
ATUALIZAR Tabela de Teste
SET Col2 = @Col2, Col3 = @Col3
FIM;
No exemplo a seguir, essa função recebe uma conexão aberta com o banco de dados de exemplo AdventureWorks, usa o método execute para chamar o procedimento armazenado UpdateTestTable e, em seguida, usa o método getUpdateCount para retornar a contagem de linhas afetadas pelo procedimento armazenado.
Copie o código do código da seguinte forma:
public static void executeUpdateStoredProcedure(Conexão con) ...{
tentar...{
CallableStatement cstmt = con.prepareCall("{chamar dbo.UpdateTestTable(?, ?)}");
cstmt.setString(1, "A");
cstmt.setInt(2, 100);
cstmt.execute();
contagem int = cstmt.getUpdateCount();
cstmt.close();
System.out.println("LINHAS AFETADAS: " + contagem);
}
pegar (Exceção e) ...{
e.printStackTrace();