Chamar função PL/SQL do Oracle dentro de uma aplicação Java

Pessoal,

Gostaria de saber o que é necessário para chamar uma função <nome da função>, que está em uma package <nome da package) no Oracle, passando os parâmetros
recebidos no lado cliente(Java) via interface Swing e enviando-os para o a função ?
Estou querendo desenvolver uma nova interface gráfica em Java(Swing/Netbeans) para uma autenticação de Usuário que existe em Delphi e cujas regras de negócio
estão implementadas via server-side no Oracle.
Alguém poderia me dar alguam dica de quais são os passos necesseários para minha aplicação Java conseguir interagir com as functions, procedures, etc, contidos nas
packages que estão no Oracle ?
Eu queria saber só a sequência de passo necessários e a sintaxe dessa chamada externa.
O resto eu vou tentando fazer aqui, se não de certo, posto a dúvida novamente.
Agradece,

Max

Fala ae tudo bem?

Estou te passando o caminho das pedras.

O código é simples dê uma olhada abaixo:

StringBuffer query = new StringBuffer();
query.append("{call procedure(?)}");

//Código para conexoes:

Connection connection = null;
PreparedStatement stmt = null;

connection = // aqui vc abre sua conexao normalmente
stmt = connection.prepareCall(query.toString());
stmt.setLong(1, &lt;parametro&gt;);
stmt.execute();

espero ter ajudado.
abraços…

nandolup,

Não estou usando Prepared Statement.
O mais correto não seria usar o Callabe Statement.
Segue o trecho mais importante da minnha função PL/SQL

CREATE OR REPLACE FUNCTION F_Operador_Valido
(P_Operador IN OPERADORES.OPE_COD_OPERADOR%TYPE,
P_Nome IN OUT OPERADORES.OPE_NOME%TYPE,
P_Senha IN OUT OPERADORES.OPE_SENHA%TYPE)
Return Char
IS

BEGIN

RETURN (‘1’);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN (‘0’);
WHEN OTHERS THEN
B_Gerais.R_Grava_Log (USER, ‘F_Operador_valido’, SQLCODE, ‘00000000’);
RETURN (‘0’);
END;

Tenho uma classe LoginUsuario, com um método AutorizaLogin, cujo código é :

public boolean AutorizaLogin(String operador, String senha) {

  query = new StringBuffer();
  query.append("{ call prpg_testes.F_OPERADOR_VALIDO(?,?,?)}");
  conexao = null;
  cstmt = null;
  retorno1 = "";
  retorno2 = "";
  
  try {
      
      // conexao
      conexao = acesso.obtemConexao();  
      cstmt= conexao.prepareCall(query.toString());
      cstmt.setString(1, operador);  
      cstmt.setString(2, senha); 
      cstmt.registerOutParameter(2,Types.VARCHAR);
      cstmt.registerOutParameter(3,Types.VARCHAR);//retorna um varchar
      cstmt.execute();
      retorno1=cstmt.getString(2);
      retorno2=cstmt.getString(3);
      JOptionPane.showMessageDialog(null,"Nome : " + retorno1);
      JOptionPane.showMessageDialog(null,"Senha : " + retorno2);
      
      return true;
      
 } catch (SQLException ex) {
        ex.printStackTrace();
        return false;
        
 } 

E criei uma classe TestaLoginUsuario, onde, definido um objeto da classe supracitada, estou chamando o método acima da seguinte forma :


public static void main(String[] args) {

    LoginUsuarioDAO login = new LoginUsuarioDAO();
    //login.ExecutaConsulta();
    if (login.AutorizaLogin("12345678","posgrad2")) {
        
        JOptionPane.showMessageDialog(null, "Acesso AUTORIZADO");
        
    } else {
        
        JOptionPane.showMessageDialog(null, "Acesso NÃO AUTORIZADO");
    }
    
}

}


Aí aparece a seguinte mensagem de erro :

init:
deps-jar:
compile-single:
run-single:
Conexão efetuada com sucesso
Conexão efetuada com sucesso
java.sql.SQLException: ORA-06550: linha 1, coluna 7:
PLS-00221: ‘F_OPERADOR_VALIDO’ não é um procedimento ou está indefinido
ORA-06550: linha 1, coluna 7:
PL/SQL: Statement ignored

    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
    at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
    at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:215)
    at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:954)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1168)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
    at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3390)
    at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4223)
    at persistencia.LoginUsuarioDAO.AutorizaLogin(LoginUsuarioDAO.java:95)
    at persistencia.TestaLoginUsuarioDAO.main(TestaLoginUsuarioDAO.java:34)

EXECUTADO COM SUCESSO (tempo total: 3 segundos)


Será que vc poderia me ajudar ?
Agradece,

Max

Select nomeDaFunção dentro de uma pstmt mesmo.

cstmt é para proc, no seu caso é uma function.

Como você pode ver daqui :


CREATE OR REPLACE FUNCTION F_Operador_Valido
(P_Operador IN OPERADORES.OPE_COD_OPERADOR%TYPE,
P_Nome IN OUT OPERADORES.OPE_NOME%TYPE,
P_Senha IN OUT OPERADORES.OPE_SENHA%TYPE)
Return Char
IS


A função recebe dois parâmetros, P_Nome e P_Senha, que também são parâmetros de saída.
Agora, o retorno da função mesmo é um Char.

Então, o que qu quero é chamar esta função PL/SQL e, dependendo do valor deste Char, se “1” , autorizar o login, se “0”, não autorizar.
Esta parte eu entendi. Se eu conseguir atribuir o valor de retorno da função a uma variável de instância, a coisa deve funcionar.
Agora o que eu questiono em elação à outra forma, Callabe Statement, é que lá eu tenho métodos para setar os parâmetros
P_Nome e P_Senha como parâmetros de saída também. Embora a P_Senha não é interessante como um parâmetro de saída, por questões de segurança, mas
como ainda estou aprendendo e estou numa fase em que o projeto ainda não é oficial, por enquanto ela pode ser retornada.
Depois vou bloquear isto.

Fico por aqui.
Vou tentar usar o Prepared Statement segunda-feira no trabalho, se eu conseguir chamar a função usando esssa sua idéia, testarei o retorno e postarei aqui.
Depois vejo como faço para obter os valores de retorno dos parâmetros P_Nome e P_Senha.
Obrigado e um bom final de semana.
Segunda a noite ou terça eu posto algum retorno aqui.
Agradece,

Max

Outra dúvida que estou também é a seguinte :

P_Operador(varchar)
e P_Senha (varchar)

seriam os campos essenciais para se autorizar o login.
Esses parâmetros receberiam os conteúdos de dois JTextFieldsl.
Agora, como a função PL/SQL possui o campo P_Nome também como parâmetro de entrada, será que vou ter
que re-escrever meu método AutorizaLogin para que o mesmo tenha 3 parâmetros(P_Operador, P_Nome e P_Senha) ?
Em resumo : eu tenho dois JTextFields(Login e Senha) contidos em JPanel que está em um JFrame.
Então, quero que esses dois parâmetros P_Operador e P_Senha, recebam o conteúdo destes dois JTextFields.
O método AutorizaLogin receberia esses conteúdos e chamaria a função PL/SQL supracitadas, sendo passados
os conteúdos desses JTextFields, da seguinte forma :

P_Operador recebe o conteúdo do JTextField -> jtfLogin

P_Senha recebe o conteúdo do JTextField -> jtfSenha

Então, a função F_OPERADOR_VALIDO, da camada de persistência, que está em banco Oracle, faria o seu serviço com estes conteúdos
e devolveria para o método AutorizaLogin um char(‘1’) se os parâmetros foram exatamente o login e senah armazenaos no banco, e um char(‘0’) para
dados inválidos.

A minha preocupação, além da sintaxe correta, que ainda não consegui achar, é com esse parâmetro P_Nome, que não existe no formulário de login(e a princípio, não
vejo necessisade de existir), mas existe na regra de negócio da função PL/SQL.

Espero ter sido claro desta vez.
Agradeço-lhe pela atenção em me ajudar.
[]'s
Max

UP

Agora na classe LoginUsuario estou fazendo assim :


String sql = “select * from prpg_testes.F_OPERADOR_VALIDO(?,?,?) ;”;

// conexao
conexao = acesso.obtemConexao();
pstmt = conexao.prepareStatement(sql);
pstmt.setString(1, operador);
pstmt.setString(2, nome);
pstmt.setString(3, senha);

pstmt.executeUpdate();

E na classe TestaLoginUsuario estou chamando assim :


if (login.AutorizaLogin(“12345678”,“Desenvolvimento”,“posgrad2”)) {

        JOptionPane.showMessageDialog(null, "Acesso AUTORIZADO");
        
    } else {
        
        JOptionPane.showMessageDialog(null, "Acesso NÃO AUTORIZADO");
    }

O erro que aparece agora é :

init:
deps-jar:
compile-single:
run-single:
Conexão efetuada com sucesso
Conexão efetuada com sucesso
java.sql.SQLException: ORA-00933: comando SQL não encerrado adequadamente

Espero que alguém consiga me ajudar.
Já faz quase uma semana que tento chamar essa função e sem nenhum sucesso.
Agradece,

Max

UP