Erro ao passar parâmetro a bloco PL/SQL [RESOLVIDO]

15 respostas
GustavoSR

Bom dia a todos.

Estou com o seguinte problema:

Tenho um bloco de PL/SQL que preciso chamar no banco.
Eu preciso passar parâmetros para este bloco.
Entretanto, estou recebndo o seguinte erro:

“Índice de coluna Invalido”

segue o erro completo:

ADF: Adding the following JSF error message:

Índice de coluna inválido

oracle.jbo.JboException:

Índice de coluna inválido

at model.financeiro.viewObj.LancFPViewImpl.gerarLancamento(LancFPViewImpl.java:363)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at oracle.adf.model.binding.DCInvokeMethod.invokeMethod(DCInvokeMethod.java:648)

at oracle.adf.model.binding.DCDataControl.invokeMethod(DCDataControl.java:2142)

at oracle.adf.model.bc4j.DCJboDataControl.invokeMethod(DCJboDataControl.java:3063)

at oracle.adf.model.binding.DCInvokeMethod.callMethod(DCInvokeMethod.java:261)

at oracle.jbo.uicli.binding.JUCtrlActionBinding.doIt(JUCtrlActionBinding.java:1635)

at oracle.adf.model.binding.DCDataControl.invokeOperation(DCDataControl.java:2149)

at oracle.jbo.uicli.binding.JUCtrlActionBinding.invoke(JUCtrlActionBinding.java:740)

at oracle.adf.controller.v2.lifecycle.PageLifecycleImpl.executeEvent(PageLifecycleImpl.java:402)

at oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding._execute(FacesCtrlActionBinding.java:252)

at oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding.execute(FacesCtrlActionBinding.java:185)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at com.sun.el.parser.AstValue.invoke(Unknown Source)

at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)

at org.apache.myfaces.trinidadinternal.taglib.util.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:53)

at org.apache.myfaces.trinidad.component.UIXComponentBase.broadcastToMethodBinding(UIXComponentBase.java:1256)

at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:183)

at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent$1.run(ContextSwitchingComponent.java:92)

at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent._processPhase(ContextSwitchingComponent.java:361)

at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent.broadcast(ContextSwitchingComponent.java:96)

at oracle.adf.view.rich.component.fragment.UIXInclude.broadcast(UIXInclude.java:102)

at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent$1.run(ContextSwitchingComponent.java:92)

at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent._processPhase(ContextSwitchingComponent.java:361)

at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent.broadcast(ContextSwitchingComponent.java:96)

at oracle.adf.view.rich.component.fragment.UIXInclude.broadcast(UIXInclude.java:96)

at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:475)

at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:756)

at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._invokeApplication(LifecycleImpl.java:788)

at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:306)

at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:186)

at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)

at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)

at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)

at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)

at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:205)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:106)

at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:446)

at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)

at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:446)

at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:271)

at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:177)

at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:111)

at java.security.AccessController.doPrivileged(Native Method)

at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)

at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:413)

at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:94)

at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:161)

at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:111)

at java.security.AccessController.doPrivileged(Native Method)

at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)

at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:413)

at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:94)

at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:161)

at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:136)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)

at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)

at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)

at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)

at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)

at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)

at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)

at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)

at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

O bloco de código que estou executando é o seguinte:

String sSQL;
            
             sSQL=new String("begin" +
                             "      dbms_scheduler.drop_job(job_name =>'JOB');" +
                             "      dbms_scheduler.create_job(job_name=>'JOB', job_type=>'PLSQL_BLOCK', auto_drop=>true," +
                             "      job_action=>'" +
                             "      declare" +
                             "      v_id_contexec NUMBER;" +
                             "      begin" +
                             "      v_id_contexec:=contexec_pkg.init_job( ? , ? , ? , ? );" +
                             "      procedure1();" +
                             "      procedure2( ? , ? );"     +
                             "      procedure3( ? , ? , ? );" +
                             "      contexec_pkg.fim_job(v_id_contexec);"   +
                             "      end;');" +
                             "      end;" +
                             "      /);");

            
                CallableStatement cstmt;
                cstmt = getDBTransaction().createCallableStatement(sSQL.toString(), 1);
            try{  
                cstmt.setInt(1,Integer.parseInt(idTipProc.toString()));
                cstmt.setInt(2, Integer.parseInt(mes.toString()));
                cstmt.setInt(3, Integer.parseInt(ano.toString()));
                cstmt.setInt(4, Integer.parseInt(idServidor.toString()));
                cstmt.setInt(5, Integer.parseInt(mes.toString()));
                cstmt.setInt(6, Integer.parseInt(ano.toString()));                 
                cstmt.setInt(7,Integer.parseInt(idTipProc.toString()));
                cstmt.setInt(8, Integer.parseInt(mes.toString()));
                cstmt.setInt(9, Integer.parseInt(ano.toString()));                 
                cstmt.execute();
                cstmt.close();
             }
            catch (Exception e) {
                jbo = new JboException(mensagem.toString()+"\n"+e.getMessage());
                jbo.setAppendCodes(false);
                throw jbo;
            }

Gostaria de saber se alguém pode me dar uma luz quanto ao que pode estar errado.

Agradeço qualquer ajuda desde já!

15 Respostas

drsmachado

Algumas considerações
1 - Esta linha at model.financeiro.viewObj.LancFPViewImpl.gerarLancamento(LancFPViewImpl.java:363) indica que o erro ocorre na linha 363. Qual é esta linha?
2 - Evite fazer conversões no momento de setar um valor ao CallableStatement. Isto é uma responsabilidade da camada de negócios, não da camada de persistência.

GustavoSR

Obrigado desde já pelo retorno drsmachado.

Esta linha já faz referência a mensagem de erro:

jbo = new JboException(mensagem.toString()+"\n"+e.getMessage());

Vou fazer as alterações referentes a conversões e testar novamente.

drsmachado

Quanto ao erro, ele se refere à incompatibilidade entre o número de argumentos e o total de parâmetros que você espera, porém, você declara 9 parâmetros e passa os 9, então, não consigo compreender onde o oracle acusa o erro.
Fonte: http://www.guj.com.br/java/95624-javasqlsqlexception-indice-de-coluna-invalido e http://www.guj.com.br/java/102861-javasqlsqlexception-indice-de-coluna-invalido--

GustavoSR

Fiz a alteração e o erro permanece.

Eu tenho a impressão de que o problema PODE estar no tamanho da String.

Só não sei como resolver.

drsmachado

Eu sou meio desconfiado quanto ao uso de String nessas ocasiões (embora acredite que não seja a causadora do erro).
Tenta criar uma StringBuffer e testar.

GustavoSR

Farei o teste.

Quando finalizar dou o retorno.

GustavoSR

Utilizei StringBuffer e o problema permanece.

Alguma outra idéia???

drsmachado

O problema definitivamente não está com a String. A questão é que, por algum motivo, o CallableStatement não recebe o total de parâmetros ou recebe a mais.
Já debugou para ver em que momento o erro é lançado?

GustavoSR

O erro é lançado quando se tenta setar o primeiro parâmetro.

na linha:

cstmt.setInt(1, p_idTipProc);
drsmachado

Bom, então há alguma outra coisa além disto.
Por padrão, o java.sql.CallableStatement recebe como argumento em um setXxx, o índex, que começa em 1 e aí segue até o limite de parâmetros.

GustavoSR

drsmachado, uma coisa que reparei em meus testes, foi que quando elimino algumas linhas do PL/SQL, a chamada funciona.
O estranho é exatamente isso.
Quando a String cresce, ele pára de funcionar e gera o erro.
Vou fazer mais alguns teste e verificar exatamente com quantos caracteres ele começa a gerar este erro.

GustavoSR

drsmachado, esta chamada serve basicamente para criar um job com a chamada de 3 procedures e fechar a conexão.
Para que o sistema não precise aguardar o retorno, pois as procedures demoram bastante.
Vc teria alguma outra idéia para fazer isso?

chamar:

proc1();

proc2(?,?,?);

proc3(?,?);

E fechar a conexão.
E não esperar o retorno do banco.
?

GustavoSR

Quando comentei as sequintes linhas, o método rodou.

query.append("begin");
//            query.append("      dbms_scheduler.drop_job(job_name =>'JOB');");
            //query.append("      dbms_scheduler.create_job(job_name=>'JOB', job_type=>'PLSQL_BLOCK', auto_drop=>true,");
            //query.append("      job_action=>'");
            query.append("      declare" );
            query.append("      v_id_contexec NUMBER;");
            query.append("      begin");
            query.append("      v_id_contexec:=contexec_pkg.init_job( ? , ? , ? , ? );");
            query.append("      proc1();");
//            query.append("      proc2( ? , ? );");
//            query.append("      proc3( ? , ? , ? );");
            query.append("      contexec_pkg.fim_job(v_id_contexec);");
//            query.append("      end;');");
            query.append("      end;");
            query.append("      end;");
//            query.append("      /);");

Preciso agora colocar as outras linhas…

GustavoSR

Não sei o motivo, mas já descobri que este bloco:

dbms_scheduler.create_job(job_name=>'JOB', job_type=>'PLSQL_BLOCK', auto_drop=>true,
job_action=>'

Faz com que as ‘?’ não sejam identificados como parâmetros.
Se eu tiro isso, funciona.

GustavoSR

Não resolvi ESTE problema, mas consegui resolver.

Coloquei o bloco em uma procedure.

Agora chamo a procedure via código normalmente e rodou.

Obrigado a todos.

Criado 14 de julho de 2011
Ultima resposta 14 de jul. de 2011
Respostas 15
Participantes 2