Erro ao executar a query

7 respostas
R

Feras estou tenho um programa que le um arquivo que esta com uma query conforme abaixo

SELECT * FROM TABELA T WHERE T.COLUNA IN (?)

esse programa eu executo através do metodo main nos argumentos do java eu add meu parametro 1,2,3,4,5 porém recebo o erro

java.sql.SQLException: ORA-01722: número inválido

se eu executar a query direto na IDE de banco funciona normalmente mais via aplicação recebo esse erro

meu codigo esta assim

String sql = readerSql(integracao.getSqlSource());
			statement = this.connection.prepareStatement(sql);

			int maxIndex = integracao.getParameter().getMaxIndex();
			int i = 1;
			while (i <= maxIndex) {
				String par = integracao.getParameter().get(i);
				statement.setObject(i, par);
				i++;
			}
			rs = statement.executeQuery();
			WriteResultSet(rs);

7 Respostas

A

Não vai funcionar. O Oracle interpreta essa lista de inteiros que você passa como se fosse uma String. Ele tenta executar a consulta assim:

SELECT * FROM TABELA T WHERE T.COLUNA IN ('1,2,3,4')

Por isso é que dá o erro ORA-01722.

A

Mas nem tudo são lágrimas...

Se compilar essa função no seu banco:

create or replace
function fnc_tab_lista(p_lista varchar2) return registro pipelined as
v_pos_separador number;
v_lista_restante varchar2(4000);
v_lista_retorno varchar2(4000);
begin

  v_lista_restante := replace(p_lista,' ','');
  v_pos_separador := instr(v_lista_restante,',');

  while v_pos_separador > 0 loop

    pipe row(trim(substr(v_lista_restante,1, v_pos_separador-1)));
    v_lista_restante := substr(v_lista_restante,(v_pos_separador+1), length(v_lista_restante));
    v_pos_separador := instr(v_lista_restante,',');

  end loop;
  pipe row(v_lista_restante);
end;

poderás utilizá-la da seguinte forma:

SELECT * FROM TABELA T WHERE T.COLUNA IN (select * from table( fnc_tab_lista(?)))

Atenção: a performance disso pode não ser a garota com quem você casaria...

R

ADEMILTON isso eu consegui descobrir em um teste que fiz aqui, será que teria alguma solução que eu possa fazer na aplicação

devido as politicas e dificuldades de se criar algo novo no banco de dados ?

D

Bom robsonsan, basta não enviar todos os números de uma vez.

A
Vejo três possibilidades:

1 - usar a função que passei;

2 - montar a instrução SQL na sua aplicação de modo que você possa concatenar os códigos que precisa passar por parâmetro. Passar a instrução final para ser executada no banco;

3 - usar EXECUTE IMMEDIATE  no Oracle, mas ainda vai dar quase na mesma que a opção 2

Eu ia editar a resposta dizendo que “em alguns casos” a performance da função pode não ser boa. Na verdade não tenho números absolutos para afirmar isso, acho que vale a pena testar.

A

Voce pode resgatar a String com a query que voce le e fazer um replace do '?' pela quantidade de parametros que voce precisa:

String strReplace = "";
while (i <= maxIndex) {
   String par = integracao.getParameter().get(i);
   statement.setObject(i, par);
   strReplace += ",?"
   i++;
}

String sql = readerSql(integracao.getSqlSource()).replace("?",strReplace.substring(1));

edit: inseri as tags code

R

Brothers isso mesmo ADEMILTON segui a 2° opção da 3 solução que vc deu show de bola resolveu meu problema

andre.almeida show tb mano fiz algo parecido e funfo

drsmachado aqui eu tenho que passar todos os parametros não tenho como correr disso

segue a solução para que possa ajudar futuras duvidas

valeus a todos.

String sql = readerSql(integracao.getSqlSource());
			int maxIndex = integracao.getParameter().getMaxIndex();
			int i = 1;
			
			while (i <= maxIndex) {
				sql = sql.replace("{" + i + "}", integracao.getParameter().get(i));
				i++;
			}
			
			statement = this.connection.prepareStatement(sql);
			rs = statement.executeQuery();
			WriteResultSet(rs);
Criado 1 de fevereiro de 2011
Ultima resposta 1 de fev. de 2011
Respostas 7
Participantes 4