Exception no PreparedStatement usando "insert .. returning id"

Olás

Estou tendo uma SQLException do postgres ao executar um “PreparedStatement”.
“Um resultado foi retornado quando nenhum era esperado”

A questão é que na query estou usando um recursos do postgres pra retornar a ID daquilo que estou inserindo


String 	qry = " INSERT INTO tb_pessoa(nome,ddd,fone, etc...) VALUES (?,?,?, etc...) RETURNING id_paciente ";

PreparedStatement 	stt 	= conn.prepareStatement(qry);

Ele deve estar retornandoo “id_paciente” para o PreparedStatement e por isso tá dando a exception.
Alguém já passou por isso ou tem alguma sugestão?

grato
abs

e ai blz!!
você de mudar:

PreparedStatement   stt     = conn.prepareStatement(qry); 

para:

PreparedStatement   stt     = conn.prepareStatement( qry, PreparedStatement.RETURN_GENERATED_KEYS );

Valeu mesmo, tava difícil encontrar!

Problema é que agora está dando outra exception:
Retorno de chaves geradas automaticamente não é suportado.

Em princípio considerei o retorno do ID, que tem como default configurado uma auto-sequencia, então troquei o valor do RETURNING por um valor fixo

String  qry = " INSERT INTO tb_pessoa(nome,ddd,fone, etc...) VALUES (?,?,?, etc...) RETURNING 1 ";  

Nada mudou (mesma exception), retirei o RETURNING e nada também…

Estou pesquisando o q pode ser, se por acaso souber ficarei duplamente agradecido.

abs

cara, to passando pela mesma situação que você, tem uma luz ai??

uso Postgres, NetBeans 6.5

flw

Putz, já faz um tempo… não consegui encontrar a solução na época e a solução foi tosca: realizei uma busca usando outra chave pra recuperar a ID (o caso foi diferente do exemplo citado).

Se vc econtrar a solução pra esse caso do postgres (alguma atualização do SGBD q venham a funcionar por ex), poste aí, por favor.

abs

kara, pelo que eu vi o driver do POSTGRESQL não suporta
esse comando: PreparedStatement stt = conn.prepareStatement( qry, PreparedStatement.RETURN_GENERATED_KEYS );

A solução que eu encontrei para obter o dado da coluna auto incrementada foi:

String sql = “INSERT INTO X(nome) VALUES(‘B’) RETURNING id”;
PreparedStatement sqlInserir = con.prepareStatement(sql);
ResultSet rs = sqlInserir.executeQuery();
if ( rs.next() ){
obj.setCodigo( rs.getInt(“id”) );
}

valeu!

mas não deu certo… :x

como estou usando sequence (não sei, mas este pode ser o problema) resolvi o problema abrindo uma transação no banco dando um SELECT na sequencia

exemplificando, ficou tudo assim:

String qry = " INSERT INTO X(nome) VALUES('B')";
stt.executeUpdate();
		  		

String 	qryId		= " SELECT CURRVAL('seq_x') as id ";
PreparedStatement 	sttId 	= conn.prepareStatement(qryId);

ResultSet rs = sttId.executeQuery();
if ( rs.next() )
	System.out.println("\n\n ID = "+rs.getString("id") );

setando a conexao ‘autocommit’ como false e no final dando o ‘commit’ dos stts

abs

Olá eu tive o problema tbm

resolvi assim:

de:

[code]
PreparedStatement ps = con.prepareStatement("insert into sistema.base " +
"(nome, permissao) " +
“values (?,?) returning id;”);

ps.setString(1, base.getNome());
ps.setString(2, base.getPermissao());

int linhasAfetadas = ps.executeUpdate();[/code]

para:

 PreparedStatement ps = con.prepareStatement("insert into sistema.base " +
                "(nome,  permissao) " +
                "values (?,?) returning id;");

ps.setString(1, base.getNome());
ps.setString(2, base.getPermissao());

ResultSet rs = ps.[b]executeQuery()[/b];

if(rs.next())
         int id = rs.getInt("id");

utilizo java 1.6
postgresql 8.3
jdbc 4 - 8.3-604
Linux Kernel 2.6.24-16-generic
e NetBeans 6.7.1 mas acho que não influencia muito

abraço

blz,
não tenho como testar agora (estou em outro projeto, sem usar Postgre/Java), mas com certeza vou me lembrar desse post numa próxima
valeu!!!

Olás, voltei para dizer o que rolou.

tralsl e fernandorochaworld , deu certo o esquema de vcs, valeu :slight_smile:

Antes não estava funcionando pois estava usando a versão 8.1, ele não reconhecia RETURNING na sintaxe.
Agora usando o Postgres 8.4 rolou blz.

Fiz o esquema do tralsl, quando inseri conn.prepareStatement( qry, PreparedStatement.RETURN_GENERATED_KEYS ); como o fernandorochaworld colocou, não fez diferença (ele ficou retornando valor 1 apenas quando omiti o “Returning” da query, pode ser pelo fato de eu estar usando sequencias para autonumerar o id).

O que ficou estranho, é que na documentação (e o que se lê por aí) diz-se para usar executeUpdate para realizar alterações/inserções, e executeQuery apenas pra busca.

abs

aê tralsl , perfect funciona q eh uma blz.