[RESOLVIDO] Function Mysql com substituição no select

Bom dia,

Tenho uma function no MySQL onde no começo dela, entre outras coisas, tenho as declarações:

[code] DECLARE var_formula varchar(500);
DECLARE ret_preco decimal(13,3);

DECLARE cursor CURSOR FOR
select CAST(var_formula as decimal(13,3)) as preco;
[/code]
Num dado momento, depois de várias substituições, etc, etc… a minha var_formula fica com um conteúdo mais ou menos assim (claro que, cada vez que dependendo da fórmula é o conteúdo, mas um exemplo):

var_formula = ‘(10.00-4.50)*30/100’

E ai, eu gostaria que ao abrir o meu cursor, ele resolvesse essa expressão, então faço isso:

OPEN cursor; FETCH cursor INTO ret_preco; CLOSE cursor;
A execução dá erro, esse erro:

Eu entendi o que está acontecendo, na verdade, qdo mando abrir o cursor, ele tá fazendo isso:

select CAST('(10.00-4.50)*30/100' as decimal(13,3)) as preco
Quando o que eu queria era que ele fizesse isso:

Perceberam a sutileza dos MALDITOS apóstrofos?!

Enfim, eu entendi o que acontece, mas não estou achando forma de resolver. Alguém sabe como faço pra que ele substitua minha var_formula no select invés de usar como um valor varchar? :roll:

Se tiver algum ex clippeiro de plantão, pra resumir, eu diria que preciso de macro-substituição. Mas como?!

Grata,
Renata

Não seria mais simples tratar a fórmula diretamente na function e retornar um bigdecimal?

É justamente o que eu estou tentando fazer.

Bem, a primeira coisa a fazer é alterar o tipo de retorno.
A segunda, é criar, dentro da function, uma forma de resolver a fórmula.
Se você puder postar a function…

[quote=drsmachado]Bem, a primeira coisa a fazer é alterar o tipo de retorno.
A segunda, é criar, dentro da function, uma forma de resolver a fórmula.
Se você puder postar a function…[/quote]

O tipo do retorno já é um decimal(13,3), não preciso alterá-lo, como vc pode ver nas declarações que postei:

Qto a segunda coisa, é exatamente por causa disso que postei aqui. Como fazer?

Sobre postar a function, o que interessa da function para demonstrar/resolver o problema eu já postei. É só juntar as partes. Vou colocar denovo o que já coloquei, desta vez tudo junto pra vc entender:

[code]
DELIMITER $$

DROP FUNCTION IF EXISTS meubd.func_guj $$
CREATE DEFINER=root@% FUNCTION func_guj() RETURNS decimal(13,3)
DETERMINISTIC
BEGIN
DECLARE var_formula varchar(500);
DECLARE ret_preco decimal(13,3);

DECLARE cur CURSOR FOR
select CAST(var_formula as decimal(13,3)) as preco;

SET var_formula = ‘(10.00-4.50)*30/100’;

OPEN cur;
FETCH cur INTO ret_preco;
CLOSE cur;

RETURN ret_preco;
END $$

DELIMITER ;[/code]

Tenta alterar o SET para

SET var_formula = SELECT ((10.00 - 4.50)*30/100);

[quote=drsmachado]Tenta alterar o SET para

SET var_formula = SELECT ((10.00 - 4.50)*30/100); [/quote]

Amigo, é óbvio que isso não funcionará.

Por favor, alguém tem alguma idéia?

Testou?
Senão, vai lá no prompt do mysql, entra com usuário e senha e executa este comando

SELECT ((10.00 - 4.50) * 30 / 100);

e verifica qual a saída.
Ela será a mesma para a tua funçãozinha

[quote=drsmachado]Testou?
Senão, vai lá no prompt do mysql, entra com usuário e senha e executa este comando

SELECT ((10.00 - 4.50) * 30 / 100);

e verifica qual a saída.
Ela será a mesma para a tua funçãozinha[/quote]

Eu sei! Mas eu não tenho o conteúdo dessa forma. Como já falei, minha fórmula está dentro de um VARCHAR, então tem apóstrofos.

E nem que eu tivesse, o comando:

Nem compila a function no MySQL pq essa sintaxe não existe!

E vc? TESTOU na function que eu passei antes de postar?! :cry:

Amigo, vc não está entendendo o problema e está indo pra algo que não tem nada haver… :frowning:

[code]
mysql> SELECT ((10.00 - 4.50)*30/100);
±------------------------+
| ((10.00 - 4.50)*30/100) |
±------------------------+
| 1.650000 |
±------------------------+
1 row in set (0.00 sec)

mysql>

[code]

Oh, compilou… Oh, a sintaxe existe…

Mais uma vez eu lembro, ninguém é obrigado a responder. Os que respondem apenas tentam ajudar. Se a ajuda não é benvinda ou não está da forma que você quer, simplesmente vá pesquisar ou tentar fazer de outra forma.

Aliás, só para constar, com as minhas alterações, essa sua funçãozinha rodou

DELIMITER $$  
  
DROP FUNCTION IF EXISTS `teste`.`func_guj` $$  
CREATE DEFINER=`root`@`%` FUNCTION `func_guj`() RETURNS decimal(13,3)  
    DETERMINISTIC  
BEGIN  
  DECLARE var_formula varchar(500);  
  DECLARE ret_preco decimal(13,3);  
  
  DECLARE cur CURSOR FOR  
    select CAST(var_formula as decimal(13,3)) as preco;  
  
  SET var_formula = (SELECT (10.00-4.50)*30/100); 
  
  OPEN cur;  
  FETCH cur INTO ret_preco;  
  CLOSE cur;  
  
  RETURN ret_preco;  
END $$  
  
DELIMITER ; 

mysql> select func_guj();
±-----------+
| func_guj() |
±-----------+
| 1.650 |
±-----------+
1 row in set (0.05 sec)

Ia responder praticamente a mesma coisa que o drsmachado colocou.
Primeiro compila e funciona sim a proc como ele colocou.
Segundo, uma educação ajuda bastante, o cara vem ajudar com boa vontade, pode estar em N situações (dando um tempo do trabalho, acabou de acordar, etc…) e pode não ter entendido como tu queria ou como ACREDITA que se expressou, um pouco de bom senso sempre é bem vindo, mesmo para as próximas respostas se necessárias.

[quote=drsmachado][code]
mysql> SELECT ((10.00 - 4.50)*30/100);
±------------------------+
| ((10.00 - 4.50)*30/100) |
±------------------------+
| 1.650000 |
±------------------------+
1 row in set (0.00 sec)

mysql>

[code]

Oh, compilou… Oh, a sintaxe existe…

Mais uma vez eu lembro, ninguém é obrigado a responder. Os que respondem apenas tentam ajudar. Se a ajuda não é benvinda ou não está da forma que você quer, simplesmente vá pesquisar ou tentar fazer de outra forma.

Aliás, só para constar, com as minhas alterações, essa sua funçãozinha rodou

DELIMITER $$  
  
DROP FUNCTION IF EXISTS `teste`.`func_guj` $$  
CREATE DEFINER=`root`@`%` FUNCTION `func_guj`() RETURNS decimal(13,3)  
    DETERMINISTIC  
BEGIN  
  DECLARE var_formula varchar(500);  
  DECLARE ret_preco decimal(13,3);  
  
  DECLARE cur CURSOR FOR  
    select CAST(var_formula as decimal(13,3)) as preco;  
  
  SET var_formula = (SELECT (10.00-4.50)*30/100); 
  
  OPEN cur;  
  FETCH cur INTO ret_preco;  
  CLOSE cur;  
  
  RETURN ret_preco;  
END $$  
  
DELIMITER ; 

mysql> select func_guj();
±-----------+
| func_guj() |
±-----------+
| 1.650 |
±-----------+
1 row in set (0.05 sec)[/quote]

Amigo, vou tentar denovo te explicar, eu não tenho a expressão! Ela está dentro de um VARCHAR, então tem APÓSTROFOS. Do jeito que vc fez claro que funciona, mas eu não tenho isso ai! Por isso estou dizendo que vc não está entendendo. Vc fez isso:

[code]DELIMITER $$

DROP FUNCTION IF EXISTS teste.func_guj $$
CREATE DEFINER=root@% FUNCTION func_guj() RETURNS decimal(13,3)
DETERMINISTIC
BEGIN
DECLARE var_formula varchar(500);
DECLARE ret_preco decimal(13,3);

DECLARE cur CURSOR FOR
select CAST(var_formula as decimal(13,3)) as preco;

SET var_formula = (SELECT (10.00-4.50)*30/100);

OPEN cur;
FETCH cur INTO ret_preco;
CLOSE cur;

RETURN ret_preco;
END $$

DELIMITER ;[/code]

Mas o que eu tenho é isso:

[code]DELIMITER $$

DROP FUNCTION IF EXISTS teste.func_guj $$
CREATE DEFINER=root@% FUNCTION func_guj() RETURNS decimal(13,3)
DETERMINISTIC
BEGIN
DECLARE var_formula varchar(500);
DECLARE ret_preco decimal(13,3);

DECLARE cur CURSOR FOR
select CAST(var_formula as decimal(13,3)) as preco;

SET var_formula = (SELECT ‘(10.00-4.50)*30/100’); – tá vendo os APÓSTROFOS!!!

OPEN cur;
FETCH cur INTO ret_preco;
CLOSE cur;

RETURN ret_preco;
END $$

DELIMITER ;[/code]

Entendeu agora pq não funciona? Sei bem que ngn é obrigado a responder. E páre de se fazer de ofendido, eu apenas tentei te mostrar que não é isso, páre de se gastar que não é isso.
E não se preocupe, estou aqui há mais tempo que vc e não faço perguntas que eu não tenha pesquisado antes. A prova de que minha dúvida não é simples e encontrável em uma pesquisa qualquer é que ngn até agora se manifestou pra resolvê-la.

Depois me perguntam pq eu fico tempos sem aparecer no GUJ. Realmente… isso aqui não é mais o que era antes… :frowning:

[quote=RenataFA]
Sobre postar a function, o que interessa da function para demonstrar/resolver o problema eu já postei. É só juntar as partes. Vou colocar denovo o que já coloquei, desta vez tudo junto pra vc entender:[/quote]
Realmente, não havia “tudo o que interessa da function”.
A única solução que vejo para isto é desmembrar o parâmetro e montar a consulta dinamicamente.

Vai dar muito mais trabalho, mas pode funcionar.

E não, isso aqui não é mais como era antigamente, faltam pessoas que conheceram isto aqui desde o seu começo, faltam pessoas com interesse em responder e não apenas colocar discussões sobre esta ou aquela empresa, sobre isto ou aquilo, faltam pessoas que ajudem a elevar o nível das respostas aqui.
Afinal, os mais “antigos” sempre esquecem que existem novatos precisando de respostas…

[quote=drsmachado][quote=RenataFA]
Sobre postar a function, o que interessa da function para demonstrar/resolver o problema eu já postei. É só juntar as partes. Vou colocar denovo o que já coloquei, desta vez tudo junto pra vc entender:[/quote]
Realmente, não havia “tudo o que interessa da function”.
A única solução que vejo para isto é desmembrar o parâmetro e montar a consulta dinamicamente.

Vai dar muito mais trabalho, mas pode funcionar.

E não, isso aqui não é mais como era antigamente, faltam pessoas que conheceram isto aqui desde o seu começo, faltam pessoas com interesse em responder e não apenas colocar discussões sobre esta ou aquela empresa, sobre isto ou aquilo, faltam pessoas que ajudem a elevar o nível das respostas aqui.
Afinal, os mais “antigos” sempre esquecem que existem novatos precisando de respostas…[/quote]

rs… Aha! Agora vc releu e viu que não tinha nada haver né? E vai falar que eu não tinha dito tudo? rs… ok ok… que seja, se isso te deixa menos magoado, pra mim não muda nada.

Vc tem total razão! Faltam msm pessoas pra ajudar a elevar o nível de respostas, concordo plenamente. E tenho a sensação de que cada dia vão faltar mais!

E qto “aos que esquecem dos novatos precisando de respostas”, eu nem vou falar nada. Afinal, vc nem me conhece, não tem culpa. E não preciso responder pq quem me conhece, me manda e-mail, me manda msg em private, etc, etc… sabe do que se precisa saber.

Só achei feio vc ser tão apelativo. Mas cada um é cada um né?

A gente tenta explicar uma dúvida, e arranja um inimigo. Ruim isso.

Qto a minha dúvida, deixa pra lá. Vou tentar em outro lugar, aqui não dá mais, ngn mais vai responder.

Obrigada à todos e aos moderadores: podem fechar o tópico, não serviu pra nada msm.

Grata,
Renata

???
Tá tenso isso…

Olá,

RenataFA, e se você removesse esses apostrófos quando fosse executar a tal fórmula!?

Antes de execução do cursor, você poderia fazer um tratamento desse VARCHAR para a remoção dos apostrófos!?

Não tentei fazer esse teste, mas como você está com a ‘mão na massa’ poderia testar para ver se funciona.

Abs!

Tudo de acordo com as regras e objetivos do fórum, por sinal.
Assim o conhecimento se dissemina…

Fica complicado quando as coisas partem para esse lado.
Aí o pessoal reclama quando começam a mandar MP, adicionar no msn…

Quanto à tua dúvida, bem, a forma como a mesma foi colocada deixa margens para isto. Principalmente pelo fato de haver um SET. Ora, se está setando um valor arbitrário à uma variável declarada, ele pode ser qualquer valor, no meu entender.
Agora, quando esse valor vem de uma entidade externa (como parâmetro de entrada), aí sim, eu compreendo que não se pode modificá-lo.

Só peço que, encontrando uma resposta adequada, retorne e a coloque aqui, para que não seja preciso enviar MP com uma pergunta igual.

Muito tenso jaziel.rc! rs… :wink:

Então newbcc, juro que era o que eu queria. Mas não consigo pensar como! Pq assim, não são apóstrofos que eu inseri, são os apóstrofos que ele interpreta ao concatenar minha variável var_formula na instrução select.
Eu até (ridiculamente) tentei fazer um REPLACE tirando os mas claro que não funciona né… :frowning: Como vc acha que eu podia fazer isso?

Alias, não precisa ser exatamente dessa forma. Já pensei em criar uma temporária, jogar o conteúdo, tentar pegar, etc, etc… mas sempre me deparo com os malditos apóstrofos! Eu só preciso interpretar a fórmula, não precisa nem ser usando select. Algum outro jeito?

Ah… e drsmachado? Pode deixar viu! Eu prometo! Deixa comigo! :stuck_out_tongue:

Olá Renata,

eu não tenho alternativa, realmente a substituição não é válida e não faria sentido.

O quê eu estou pensando nesse momento é se existe a possibilidade de você, ao invés de usar essa expressão toda ‘10.00 - 4.50…’, enviar o resultado direto dela para a sua função, pois assim você estaria trabalhando direto com o double.

Se você entendeu a minha intenção, é possível para você fazer essa implementação?

Abs!

Newbcc, foi o que sugeri desde o início, mas ela não tem como fazer isto.