Jump to content
Edilson Chaves

Criar um novo registro com CURSOR no MySql

Recommended Posts

Ola amigos, uso curso a algum tempo, só que desta vez estou apanhando de algo que aparentemente e bem simples. Tenho certeza que estou esquecendo algum detalhe.

To a 2 dias me debatendo com isto.

Por isto estou pedindo ajuda.

 

O que pretendo fazer e criar um novo registro que mostre a evoluçao do crecimento mensal projetando o ponto de equilibrio. Para isto eu preciso pegar a soma do mês anterior e acrescentar a soma do atual.

 

Esta é a Procedure. Abaixo explico o quer nao esta funcionado.

 

DROP PROCEDURE IF EXISTS sp_Monitorado;

DELIMITER $$
    CREATE PROCEDURE sp_Monitorado()
    BEGIN
        DECLARE done INT DEFAULT FALSE;
        DECLARE vVlrMesAtuPrv, vVlrMesAntPrv, vVlrMesAtuRea, vVlrMesAntRea, vPrevisto, vRealizado numeric(10,2);
        DECLARE vAnoAtu, vMesAtu, vOrdem, vAno, vMes INT;
        DECLARE vGrupo, vSubGrupo, vPessoa, vPessoaAtu VARCHAR(100);
        DECLARE cDados CURSOR FOR SELECT Ordem, Grupo, SubGrupo, Pessoa, Ano, Mes, Previsto, Realizado FROM vwresultadomonitoramento;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

        OPEN cDados;

        read_loop: LOOP

            FETCH cDados INTO vOrdem, vGrupo, vSubGrupo, vPessoa, vAno, vMes, vPrevisto, vRealizado;

            IF done THEN
               LEAVE read_loop;
            END IF;

            IF vOrdem <= 4 THEN
                SET vVlrMesAtuPrv = vVlrMesAtuPrv + vPrevisto;
                SET vVlrMesAtuRea = vVlrMesAtuRea + vRealizado;
            INSERT INTO zzResultado VALUES (vOrdem, vGrupo, vSubGrupo, vPessoa, vAno, vMes, vPrevisto, vVlrMesAtuPrv);
            END IF;

            IF vOrdem = 4 THEN
                SET vVlrMesAntPrv = vVlrMesAntPrv + vVlrMesAtuPrv;
                SET vVlrMesAntRea = vVlrMesAntRea + vVlrMesAtuRea;
                INSERT INTO zzResultado VALUES (99, vGrupo, 'PONTO DE EQUILIBRIO', vPessoa, vAno, vMes, vVlrMesAntPrv, vVlrMesAntRea);
                SET vVlrMesAtuPrv = 0;
                SET vVlrMesAtuPrv = 0;
            END IF;

        END LOOP read_loop;

        CLOSE cDados;
    END;
$$ DELIMITER;

 

Quando co cursor entra nesta condiçao abaixo ele deveria pegar o valor acumulado anterior e acrescentar as variaveis (vVlrMesAntPrv, vVlrMesAntRea). So que o valor se perde e fica tudo zerado.

Alguém pode me dizer onde estou errando.

Anexo tem um print do resultado que pretendo ter

 

 IF vOrdem = 4 THEN
                SET vVlrMesAntPrv = vVlrMesAntPrv + vVlrMesAtuPrv;
                SET vVlrMesAntRea = vVlrMesAntRea + vVlrMesAtuRea;
                INSERT INTO zzResultado VALUES (99, vGrupo, 'PONTO DE EQUILIBRIO', vPessoa, vAno, vMes, vVlrMesAntPrv, vVlrMesAntRea);
                SET vVlrMesAtuPrv = 0;
                SET vVlrMesAtuPrv = 0;

END IF;

 

PontoEquilibrio.png

Share this post


Link to post
Share on other sites

1) não exponha pessoas reais nos exemplos.

2) explique a memória de cálculo , não entendi de onde veio  o -989,35 da coluna 2.

3) pesquise pela cláusula over() pois ela permite totais acumulados (running totals)

Share this post


Link to post
Share on other sites
1 hora atrás, Motta disse:

1) não exponha pessoas reais nos exemplos.

2) explique a memória de cálculo , não entendi de onde veio  o -989,35 da coluna 2.

3) pesquise pela cláusula over() pois ela permite totais acumulados (running totals)

Motta obrigado por responder.

1) sua preocupação com expor o nome de uma cliente e valida, mas este e um nome ficticio que invetei para este exemplo.

2) nao se preocupe com estes valores que estão na frente do nome. Eles nao estão validos ainda. Será o acumulado do mes

3) Ja usei a clausula OVER no Oracle e Sql Server, nem sabia que o MySql ja tinha. No meu caso acho que ela nao se aplica.

 

Meu caso e simples. fiz um cursor que percorre uma lista ordenada por cliente, ano, mes e um ID com nome ordem.

a cada registro que ele passa, e acumulado o valor PLANEJADO em "vVlrMesAtuPrv". 

Quando ele entra condição "vOrdem = 4" deveria fazer este calculo "SET vVlrMesAntPrv = vVlrMesAntPrv + vVlrMesAtuPrv;", só que qdo entra aqui o calculo nao execulta e o valor fica ZERO.

Share this post


Link to post
Share on other sites

Não tem "ordem" faltante ou em duplicidade ?

Tua lógica supõe uma base limpa , de banho tomado e penteada ...

 

Share this post


Link to post
Share on other sites
Em 25/04/2020 at 17:27, Motta disse:

Não tem "ordem" faltante ou em duplicidade ?

Tua lógica supõe uma base limpa , de banho tomado e penteada ...

 

Se alguém tiver um problema como este, eu encontrei o problema e solução.

Por algum motivo o MySql perde o valor da Variável quando e passada por outro mais de uma condição IF ... END.

O que fiz foi criar uma variável global para todos os valores que seriam utilizados posteriormente.

 

DELIMITER $$
    CREATE PROCEDURE sp_Monitorado()
    BEGIN
        DECLARE done INT DEFAULT FALSE;
        DECLARE vPrevisto, vRealizado numeric(10,2);
        DECLARE vAnoAtu, vMesAtu, vOrdem, vAno, vMes INT;
        DECLARE vGrupo, vSubGrupo, vPessoa VARCHAR(100);
        DECLARE cDados CURSOR FOR SELECT Ordem, Grupo, SubGrupo, Pessoa, Ano, Mes, Previsto, Realizado FROM vwResultado;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    SET @PessoaAnt = (SELECT pessoa from vwResultado limit 1);
    SET @VlrMesAntPrv := 0.0;
    SET @VlrMesAntRea := 0.0;

        OPEN cDados;

        read_loop: LOOP

            FETCH cDados INTO vOrdem, vGrupo, vSubGrupo, vPessoa, vAno, vMes, vPrevisto, vRealizado;

            IF done THEN
               LEAVE read_loop;
            END IF;

      IF @PessoaAnt != vPessoa THEN
         SET @VlrMesAntPrv := 0.0;
         SET @VlrMesAntRea := 0.0;
      END IF;

      SET @VlrMesAntPrv = @VlrMesAntPrv + vPrevisto;
            SET @VlrMesAntRea = @VlrMesAntRea + vRealizado;
      SET @PessoaAnt = vPessoa;
      INSERT INTO Resultado VALUES (vOrdem, vGrupo, vSubGrupo, vPessoa, vAno, vMes, vPrevisto, vRealizado);

            IF (@PessoaAnt = vPessoa AND vOrdem = 4) THEN
                 INSERT INTO Resultado VALUES (99, vGrupo, 'PONTO DE EQUILIBRIO', vPessoa, vAno, vMes, @VlrMesAntPrv, @VlrMesAntRea);
            END IF;

        END LOOP read_loop;

        CLOSE cDados;
    END;
$$ DELIMITER;

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By landerbadi
      Olá pessoal, boa noite
       
      Tenho uma tabela no banco de dados mysql com três colunas (id, audio, tocado) e um player de audio html5 simples.
       
      <audio controls>
        <source src="horse.ogg" type="audio/ogg">
        <source src="horse.mp3" type="audio/mpeg">
      </audio>
       
      Fiz uma consulta no bd para me retornar um (1) registro. Com base nessa consulta o player toca o audio correspondente.
      Preciso fazer com que após o término do audio seja gravado na coluna 'tocado' no bd a palavra 'OK'.
      Tem como fazer isso?
    • By TeixeiraRamos
      Saúde e paz para todos,
      Prezados não sei o que vem ocorrendo com a minha procedure;
       
      No phpMyAdmin, em Editar rotina, detalhes consta:
       
       
      Em "Adicionar parâmetro"
       
       
       
      BEGIN DECLARE var_data DATE; DECLARE var_dia VARCHAR(50); DECLARE contador INT DEFAULT 0; SET var_data = data_inicial; SET var_dia = DAYNAME(data_inicial); WHILE contador < intervalo DO INSERT INTO tbpdodia(data_inicio, diassemanas)VALUES (var_data, var_dia); SET contador = contador + 1; SET var_data = DATE_ADD(data_inicial, INTERVAL contador DAY); SET var_dia = DAYNAME(var_data); END WHILE; END; DELIMITER; Call adicionar_data('2020-11-29', 398);  
      Gostaria que a coluna "data_inicial" fosse preenchida com as datas de 2020-11-29 a 2021-12-31
      O resultado mostra erros.
       
      Obrigado, saude
       
       
    • By Matheus B. Siqueira
      Olá, tento fazer uma requisição para atualização de item do accordion no mysql, porém apenas um item é atualizado.
      O código funciona da seguinte forma: É buscado perguntas referente ao vídeo selecionado no carousel, logo após, o código da Amostra de Código 1, cria os cards dentro do modal. Cada card é referente a uma pergunta diferente registrada no Banco de Dados.
      Porém, ao tentar atualizar um item do MYSQL, dentro do card, no textarea, o primeiro item (1º pergunta) desse accordion é atualizado, o segundo item (2º pergunta) não é atualizado.
      Cada pergunta possui um id no MYSQL, bem como, um assunto, uma resposta, uma pergunta... de acordo com a Figura 01.
      Vale ressaltar que, de acordo com a Amostra de Código 2, é buscado juntamente com o AJAX, todas as perguntas referente ao vídeo selecionado no carousel.
      Amostra de Código 1:
      $(document).ready(function() { $(function() { $('#responder_duvidas').click(function() { var codigoVideo2 = $('.carousel-item.active').attr('data-link_video'); var accordion2 = ""; $.post("buscar_duvida_monitor_resp.php", { codigo_video_monitor: codigoVideo2, }, function(data2, status) { if (data2 !== "Fail") { $("#dynamic_accordion #accordion").html(accordion2); // Adiciona essa linha $.each(JSON.parse(data2), function (index2, duvida3) { accordion2 += '<div class="card" style="margin: 5px">'; accordion2 += '<div class="card-header" id="heading'+index2+'">'; accordion2 += '<h5 class="mb-0">'; accordion2 += '<button class="btn btn-link" data-toggle="collapse" data-target="#collapse'+index2+'" aria-expanded="true" aria-controls="collapse'+index2+'">'; accordion2 += duvida3.assunto; accordion2 += '</button>'; accordion2 += '</h5>'; accordion2 += '</div>'; accordion2 += '<div id="collapse'+index2+'" class="collapse" aria-labelledby="heading'+index2+'" data-parent="#accordion">'; accordion2 += '<div class="card-body">'; accordion2 += '<div style="background: #ddd; color #fff; padding: 10px 20px; border-radius: 5px">'; accordion2 += duvida3.pergunta; accordion2 += '</div>'; accordion2 += '<hr>'; accordion2 += '<div style="background: #fff; color #fff; padding: 10px 20px; border-radius: 5px">'; accordion2 += '<form method="post" enctype="multipart/form-data">'; accordion2 += '<textarea class="form-control" name="resposta" id="resposta" required>'+duvida3.resposta+'</textarea>'; accordion2 += '<input type="hidden" id="id_duvidas" value="'+duvida3.idduvidas+'" />'; accordion2 += '<br><button type="button" id="enviar_resposta" class="btn btn-success btn-sm">Enviar resposta</button>'; accordion2 += '</form>'; accordion2 += '</div>'; accordion2 += '</div>'; accordion2 += '</div>'; accordion2 += '</div>'; $("#dynamic_accordion #accordion").html(accordion2); }); } }); }); $(document).on("click", "#enviar_resposta",function(){ $.ajax({ url: "atualizar_resposta.php", method: "POST", data: { resposta: $('#resposta').val(), idduvidas: $('#id_duvidas').val() }, success: function(res) { var data = JSON.parse(res); alert((data.success == true) ? "Pergunta atualizada" : "Pergunta não atualizada"); $('.modal-backdrop').remove(); return; } }); // fecha modal $("#modalDuvidas").modal("hide"); }); }); }); Figura 1:

       
       
      Amostra de Código 2:
      <?php if (isset($_POST['idduvidas']) && isset($_POST['resposta'])) { $id_resposta = $_POST['idduvidas']; $resposta = $_POST['resposta']; $servidor = 'localhost'; $usuario = 'root'; $senha = 'root'; $banco = 'onteach'; $conexao = mysqli_connect($servidor,$usuario,$senha,$banco); $consulta2 = "UPDATE duvidas SET duvidas.resposta = '$resposta' WHERE duvidas.idduvidas = '$id_resposta'"; die(json_encode(['success'=>(mysqli_query($conexao, $consulta2))])); } Figura 2 (FIGURA COMPLEMENTAR APRESENTANDO O ACCORDION NO WEBSITE)

       
      Por fim, este tópico auxilia em um tema que é específico, porém, pode ser utilizado para outros fins de programação, bem como, a utilização de definição de váriantes em accordion com maiores itens.
      Desde já, agradeço.
       
    • By gersonab
      tenho uma data no BD , gostaria de mostrar ela 15 dias antes, montando um alerta 15 dias antes desta data
      atualmente utilizo assim, porém me mostra 15 dias após.
      $data = DateTime::createFromFormat('d/m/Y', $datab); $data->add(new DateInterval('P15D')); tipo:
      se eu colocar a data 24/11/2020 , ela vai me mostrar 09/12/2020 , quando preciso q mostre 09/11/2020.
    • By david2007
      Endpointer Framework é um Framework PHP para construção de APIs REST com Programação Procedural.
       
      Todas as regras de negócio são implementadas como Stored Procedures.
       
      http://endpointer.com
       
      Endpointer Framework é Código Aberto sob a licença MIT

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.