[Resolvido] Utilizando insert com funções do MySql em JDBC

Olá, boa tarde.

Tenho o seguinte método para cadastrar Ordens de serviço:

public void add(Os o) {
    
    Connection con = ConnectionBank.getConnetion();
    PreparedStatement pstmOs = null;

try
{
 pstmOs = con.prepareStatement("INSERT INTO os (FkTipo, FkSetor, FkPrioridade, FkSituacao, FkSolicitante, FkLogin, DiaHora, Problema, Solucao, Excluido) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
 
 pstmOs.setInt(1, o.getFkTipo());
 pstmOs.setInt(2, o.getFkSetor());
 pstmOs.setInt(3, o.getFkPrioridade());
 pstmOs.setInt(4, o.getFkSitucao());
 pstmOs.setInt(5, o.getFkSolicitante());
 pstmOs.setInt(6, o.getFkLogin());
 pstmOs.setDate(7, Date.valueOf(o.getDia()));
 pstmOs.setString(8, o.getProblema());
 pstmOs.setString(9, o.getSolucao());
 pstmOs.setString(10, o.getExcluido());
 pstmOs.execute();
 
 JOptionPane.showMessageDialog(null, "A Ordem de serviço foi lançada com sucesso.", "AVISO", JOptionPane.INFORMATION_MESSAGE);
}
catch (SQLException | HeadlessException ErroSql)
{
    JOptionPane.showMessageDialog(null, "ERRO AO CADASTRAR. \n"+ErroSql, "ERRO", JOptionPane.ERROR_MESSAGE);
}    
finally
{
    ConnectionBank.closeConnection(con, pstmOs);
}

Este método funciona normalmente, porém gostaria de utilizar a função Now() para gravar com a data e a hora do servidor, a dúvida é como inserir a função dentro do meu insert para que eu consiga fazer a gravação?

pstmOs = con.prepareStatement("INSERT INTO os (FkTipo, FkSetor, FkPrioridade, FkSituacao, FkSolicitante, FkLogin, DiaHora, Problema, Solucao, Excluido) VALUES (?, ?, ?, ?, ?, ?, Now(), ?, ?, ?);");

Tentei dessa forma e não consegui, ele alega número errado de parâmetros, e também não sei como utilizar o preparedStatment: pstmOs.setDate(7, Date.valueOf(o.getDia()));, seria necessário a criação de uma trigger?

Remova o “ ; “ de dentro da sua string SQL, ele só é necessário para a execução do comando diretamente no SGBD, não no Java.

Sobre o parâmetro de data segue o link abaixo:

Eu entendi a sugestão, porém eu gostaria de utilizar Now() da função MySql é possivel fazer direto pela String de insert?

Tem como sim, basta informar na string SQL a função!

Exemplo:

try {
 pstmOs = con.prepareStatement("INSERT INTO os(FkTipo, FkSetor, FkPrioridade, FkSituacao, FkSolicitante, FkLogin, DiaHora, Problema, Solucao, Excluido) VALUES (?, ?, ?, ?, ?, ?, NOW(), ?, ?, ?)");
 
 pstmOs.setInt(1, o.getFkTipo());
 pstmOs.setInt(2, o.getFkSetor());
 pstmOs.setInt(3, o.getFkPrioridade());
 pstmOs.setInt(4, o.getFkSitucao());
 pstmOs.setInt(5, o.getFkSolicitante());
 pstmOs.setInt(6, o.getFkLogin());
 //Não existe parâmetro de data, pois foi utilizada a função NOW()
 pstmOs.setString(7, o.getProblema());
 pstmOs.setString(8, o.getSolucao());
 pstmOs.setString(9, o.getExcluido());
 
 pstmOs.executeUpdate();
 
 JOptionPane.showMessageDialog(null, "A Ordem de serviço foi lançada com sucesso.", "AVISO", JOptionPane.INFORMATION_MESSAGE);
} catch (SQLException | HeadlessException ErroSql) {
    JOptionPane.showMessageDialog(null, "ERRO AO CADASTRAR. \n"+ErroSql, "ERRO", JOptionPane.ERROR_MESSAGE);
} finally {
    ConnectionBank.closeConnection(con, pstmOs);
}

Tentei dessa forma, porém, não funcionou.

Qual o erro que é exibido no log?

Simulei um teste aqui e funcionou corretamente.

acredito que esse comentário é inválido e o problema não é por causa dele

O problema principal acredito que era por ele informar NOW() na string SQL e tentar informar o parâmetro de data na posição 7, o que provavelmente ocasionava o erro!
O fato de remover o “ ; ” é somente para evitar problemas que possam vir a ocorrer, pois no passado eu já tive problemas com isso, e outras pessoas aqui do fórum também tiveram, pois me recordo de ter auxiliado alguns usuários com essa mesma questão.

Então, o erro é na hora de reconhecer os parâmetros.

Screenshot_1

O problema é pela quantidade de parâmetros isso eu concordo, mas, no caso MySQL eu posso executar outra SELECT após a primeira, e isso não confere de ter o ; pode ter sim, mas, é desnecessário nesse contexto.

você deve estar passando mais paramentos do que precisa, e o framework está confundido pela quantidade e tipo. Se eu fosse você usaria tudo parâmetro e colocaria a data atual via código

Sim, testei das duas formas, não fez diferença alguma.

Veja o exemplo que coloquei, você está informando parâmetros em posições a mais do que é esperado!

Realmente, verifiquei nesse momento em que você falou, e sim, estava com mais parâmetros do que o necessário.

Só a nível de curiosidade, quando você afirma em executar um select após a 1ª instrução, isso seria dentro da mesma string SQL?
Não seriam comandos distindos executados separadamente pelo pst?

Aqui um item explicando: https://stackoverflow.com/a/10929795/6797930 a execução de múltiplas SQL na mesma Statement. Nesse Caso foi utilizado outra técnica, mas, que recai na separa por ;

Esse é outro exemplo: https://docs.microsoft.com/en-us/sql/connect/jdbc/using-multiple-result-sets?view=sql-server-2017

Por exemplo: você quer pegar o Id Inserido.

2 curtidas

Interessante, eu não conhecia essa possibilidade de uso, sempre trabalhei com execuções únicas e distintas.

2 curtidas