Problemas ao fazer chamada a functions pl/sql sobrecarregados

11 respostas
F

Olá

Estou com dificuldades ao fazer uma chamada via PreparedStatement a uma função pl/sql com sobrecarga. O erro é esse
Caused by: java.sql.SQLException: ORA-06550: line 1, column 13:
PLS-00307: too many declarations of 'FUN_AUTENTICA_USUARIO' match this call
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

	at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
	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:1119)
	at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1278)
	at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3415)
	at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3520)
	at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:5090)
	at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:168)
	at br.com.xxxx.xxxx.persistencia.PacAgeWebCall.executaAutenticaUsuario(PacAgeWebCall.java:634)
	... 23 more
log4j:ERROR Failed to excute sql
java.sql.SQLException: ORA-06550: line 2, column 38:
PLS-00103: Encountered the symbol "FUN_AUTENTICA_USUARIO" when expecting one of the following:

   . ( ) , * @ % & | = - + &lt / &gt at in is mod not range rem =&gt
   .. <an exponent (**)> &lt&gt or != or ~= &gt= &lt= &lt&gt and or like as
   between from using ||
Se eu deixar apenas uma função funciona normamente. Testando as funçoes sobrecarregadas pelo PL/SQL developer também funciona

Obrigado

11 Respostas

O

Faz tempo que eu não programo em PL/SQL. O que é exatamente esta sobrecarga? Seria isto http://download-east.oracle.com/docs/cd/B14117_01/appdev.101/b10807/08_subs.htm#i12352?
É que eu nunca fiz isto. Não sabia que isto existia. Não é mais fácil criar uma function com outro nome? 8)

Dois chutes:
:arrow: Usar CallableStatement ao invés de PreparedStatement.
:arrow: Usar outra versão do driver JDBC da Oracle (mais recente). Para testar isto, use o Squirrel para conectar no Oracle e rodar o PL/SQL.

F

A sobrecarga é examente o que o link que vc passou trata. Tenho duas funções de mesmo com número de parametros diferentes.
Eu criei outra função mesmo.
Apesar de que essa sobrecarga seria muito util pelo menos pra mim, mas como ela não funcionou… :frowning:
Obrigado oyama pelas dicas.

O

Curiosidade: como você pretendia usar isto via Java? Você estava usando setInt, setDate, setString ou estava usando setObject?

F

Eu tentei usar fazendo uma chamada normal a procedure
Se o número de parametros for 3 chama uma função

cs = con.prepareCall("{ ? = call FUN_RETORNA_DADOS(?,?,?);

Se o número de parametros for 5 chama outra

cs = con.prepareCall("{ ? = call FUN_RETORNA_DADOS(?,?,?,?,?);

Era assim que estava tentando usar.
(Pelo menos era assim que eu imaginava)

O

furutani:
Eu tentei usar fazendo uma chamada normal a procedure
Se o número de parametros for 3 chama uma função

cs = con.prepareCall("{ ? = call FUN_RETORNA_DADOS(?,?,?);

Se o número de parametros for 5 chama outra

cs = con.prepareCall("{ ? = call FUN_RETORNA_DADOS(?,?,?,?,?);

Era assim que estava tentando usar.
(Pelo menos era assim que eu imaginava)

Neste exemplo que você passou eu realmente não vi vantagem nenhuma de fazer overloading da function em PL/SQL, pois você teria que ter dois CallableStatement.

F

A vantagem não é desse ponto de vista.
A vantagem é que eu posso ter 2 function com o mesmo nome.
Dependendo do nosso cliente eles nao atualizam o war e ficam com a chamada a função antiga com 3 parametros apenas.
Enquanto os que atualizarem o war podem usar a function com 5 parametros.

O

furutani:
A vantagem não é desse ponto de vista.
A vantagem é que eu posso ter 2 function com o mesmo nome.
Dependendo do nosso cliente eles nao atualizam o war e ficam com a chamada a função antiga com 3 parametros apenas.
Enquanto os que atualizarem o war podem usar a function com 5 parametros.

Desculpe a insistência e a ignorância, mas de novo não vi vantagem nenhuma. Você está dizendo que poderia ter duas stored procedures no banco com nomes iguais, mas que fazem coisas diferentes (tem a parte em comum mas no fundo a funcionalidade interna é direrente, pois não deve ter algo como super() 8) ) e tem um número diferentes de parâmetros e que dependendo do cliente você queria que um chamasse um ou outro, mas que para isto você teria que fazer um deploy diferente. Onde está a vantagem disto?
Pensando em análise estruturada se a função tem comportamento diferente de uma outra função, elas são diferentes. Não é por que o nome é igual que elas tem algo em comum. Se você queria usar isto para manter os “contratos” iguais, isto está furado, pois no fundo são duas funções diferentes e não compartilham nada entre elas (só o nome para dar uma idéia de funcionalidade). Para mim esta feature de overloding em PL/SQL é uma furada (PL/SQL não é uma linguagem OO). Vai dar mais dor de cabeça de manutenção.

J

Basicamente, eu entendi que a forma que vc utilizou para setar parâmetros deixou ambígua qual função deveria ser chamada. para saber exatamente o que aconteceu, deveria ver melhor as funções no PL/SQL e como vc as chamou, mas é isso.

Lembre-se que o Oracle pode fazer conversões para o tipo de dado que a função têm, então deve ter mais de uma função com a mesma quantidade de parâmetros, e vc pode estar passando, por exemplo, um String, que pode ser convertido para number ou ser interpretado como varchar2, e aí o SQL não sabe qual função vc quer.

Quando a ser furada ou não, se as funções realizam a mesma tarefa (autenticar usuário), me parece bem válido que tenham o mesmo nome. Já usei sobrecarga em PL/SQL nesse tipo de situações principalmente para permitir que códigos antigos e novos compartilhem regras de negócios sem ter que atualizar tudo…

F

Olá

Vou explicar um pouco mais do problema para ambientar você melhor.
A aplicação que desenvolvo já está em produção há algum tempo, recentemente foi implementado uma funcionalidade nova e isso implicou na introdução de novos parâmetros em uma das functions que já estavam em produção.
Acontece que essa function está dentro de uma package do oracle, com outras functions e procedures e houve a necessidade de atualiza-la em produção (não por causa dessa function sobrecarregada).
O que não obriga a fazer um novo deploy.

Eu não preciso fazer um deploy diferente ou o cliente não quer, então eu preciso manter o deploy antigo funcionando, ou seja, tem que ser mantido pelo menos a assinatura da function anterior, dai a function antiga (com menos parametros) chamaria a nova (com mais parametros).
E quem quisesse fazer o deploy da nova versão usaria sem problemas tbem.

F

No meu caso as funçoes se diferem em número de parâmetros, voce acha que mesmo assim o problema pode estar na forma de setar parametros?

Voce sacou o q eu estou fazendo.

J

Vá no seu sql/plus e dê um desc dessa sua função?

Sabe o que vai acontecer? Só aparecerá uma delas. E por que? Por que só existe uma.

Faça o seguinte, coloque as duas numa package e seus problemas acabaram-se.

Criado 21 de março de 2007
Ultima resposta 22 de mar. de 2007
Respostas 11
Participantes 4