USUÁRIO:      SENHA:        SALVAR LOGIN ?    Adicione o VBWEB na sua lista de favoritos   Fale conosco 

 

  Fórum

  Visual Basic
Voltar
Autor Assunto:  Erro no MySQL 5
Fabio_PB
PATOS
PB - BRASIL
Postada em 03/08/2006 08:39 hs            
Olá. Criei um procedimento no MySQL que atualiza o saldo do estoque do produto
este procedimento é chamado em um trigger (após a inserção na tabela de entradas, por exemplo) só que ao executar o MySQL me retorna o erro 1415 'NOT ALLOWED TO RETURN A RESULT SET FROM A TRIGGER'. Se alguém poder ajudar desde já agradeço. OBS. Já tentei utilizar o DECLARE ... HANDLER para solucionar o problema, O DECLARE ... HANDLER está como comentário no procedimento abaixo:
 
/* TRIGGER DE CHAMADA */
 
DROP TRIGGER tab_BalancosItens_InsereSaldoProduto;
DELIMITER //
CREATE TRIGGER tab_BalancosItens_InsereSaldoProduto AFTER INSERT ON tab_BalancosItens FOR EACH ROW
BEGIN
     CALL atualizaEstoque(NEW.BalancoItem_ProdutoID);
END//
DELIMITER ;
 
/* PROCEDIMENTO DE ATUALIZACAO DO ESTOQUE */
DROP PROCEDURE atualizaEstoque;
DELIMITER //
CREATE PROCEDURE atualizaEstoque(produto INTEGER)
BEGIN
     DECLARE dataInicial DATE;
     DECLARE qtdBalancos, qtdEntradas, qtdSaidas, qtdVendas DOUBLE;
     DECLARE produto INTEGER;
     /*
     DECLARE CONTINUE HANDLER FOR 1329 SET X = 'NO ROWS ';
     DECLARE CONTINUE HANDLER FOR 1415 SET X = 'NOT ALLOWED ';
     SET X = 'NUNHUM ERRO';
     */
     SELECT B.BalancoData,SUM(BI.BalancoItem_Quantidade)
           FROM tab_Balancos B, tab_BalancosItens BI
           WHERE BI.BalancoItem_BalancoID = B.BalancoID AND
                BI.BalancoItem_ProdutoID = produto AND
                BI.BalancoItem_BalancoID = (SELECT MAX(B.BalancoID) FROM tab_Balancos)
           GROUP BY BI.BalancoItem_ProdutoID;
    
     SET dataInicial = IFNULL(dataInicial,CURDATE());
     SET qtdBalancos = IFNULL(qtdBalancos,0);
     
     SELECT IFNULL(SUM(EI.EntradaItem_Quantidade),0) INTO qtdEntradas
           FROM tab_Entradas E, tab_EntradasItens EI
           WHERE EI.EntradaItem_EntradaID = E.EntradaID AND
                E.EntradaData >= dataInicial AND EI.EntradaItem_ProdutoID = produto
           GROUP BY EI.EntradaItem_ProdutoID;
          
     SELECT IFNULL(SUM(SI.SaidaItem_Quantidade),0) INTO qtdSaidas
           FROM tab_Saidas S, tab_SaidasItens SI
           WHERE SI.SaidaItem_SaidaID = S.SaidaID AND
                S.SaidaData >= dataInicial AND SI.SaidaItem_ProdutoID = produto
           GROUP BY SI.SaidaItem_ProdutoID;
     SELECT IFNULL(SUM(VI.VendaItem_Quantidade),0) INTO qtdVendas
           FROM tab_Vendas V, tab_VendasItens VI
           WHERE VI.VendaItem_VendaID = V.VendaID AND
                V.VendaData >= dataInicial AND VI.VendaItem_ProdutoID = produto
           GROUP BY VI.VendaItem_ProdutoID;
          
     SET qtdEntradas = IFNULL(qtdEntradas,0);
     SET qtdSaidas = IFNULL(qtdSaidas,0);
     SET qtdVendas = IFNULL(qtdVendas,0);
    
     UPDATE tab_Produtos
           SET ProdutoSaldoEstoque = IFNULL((qtdBalancos+QtdEntradas)-(qtdVendas+qtdSaidas),0)
           WHERE ProdutoID = produto;
          
END//
DELIMITER ;
     
kerplunk
Pontos: 2843 Pontos: 2843 Pontos: 2843
SÃO PAULO
SP - BRASIL
Postada em 03/08/2006 17:09 hs         
'NOT ALLOWED TO RETURN A RESULT SET FROM A TRIGGER'. Quer dizer 'VOCÊ NÃO PODE RETORNAR UM RESULT SET DE UMA TRIGGER'
     
Fabio_PB
PATOS
PB - BRASIL
Postada em 04/08/2006 10:47 hs            
Olá. Consegui resolver meu problema. Comecei a resolve-lo dividindo-o em partes.
 
As tabelas envolvidas(estão resumidas):
 
 - tab_Produtos(ProdutoID, ProdutoDescricao, ProdutoSaldoEstoque)
 - tab_Balancos(BalancoID, BalancoData)
 - tab_BalancosItens (BalancoItem_ID, BalancoItem_BalancoID, BalancoItem_ProdutoID,
     balancoItem_quantidade)
 OBS: As tabelas de entradas(tab_Entradas, tab_EntradasItens),
     saidas(tab_Saidas, tab_SaidasItens) e
     vendas(tab_Vendas, tab_vendasItens) seguem o modelo das de balancos.
     As tabelas de saídas, são usadas para saídas que não sejam vendas, estravio de produtos por      exemplo.

Criei algumas funções para retornar os valores esperados:
 
 - getDataUltBalanco():data - Retorna a data do ultimo balanço, a partir desta data serão contabilizadas as quantidades de entradas, saidas e vendas.
 - getQtdBalanco(produto:inteiro):duplo - Retorna a quantidade total de um determinado produto informado no ultimo balanço.
 - getQtdEntradas(produto:inteiro, dataInicial:data):duplo - Retorna a quantidade total de entradas de um determinado produto informado a partir da data obtida com a função getDataUltBalanco().
 - getQtdSaidas(produto:inteiro, dataInicial:data):duplo - Retorna a quantidade total de saidas de um determinado produto informado a partir da data obtida com a função getDataUltBalanco().
 - getQtdVendas(produto:inteiro, dataInicial:data):duplo - Retorna a quantidade total de vendas de um determinado produto informado a partir da data obtida com a função getDataUltBalanco().
 
 OBS: Nas funções abaixo, o DECLARE ... HANDLER foi alterado, para que ao tentar selecionar um dado e este não for encontrado, um valor padrão seja selecionado, sem interromper assim a execução da função.
 
 Note, também que o codigo das funções getQtdSaida e getQtdVenda não diferem da função getQtdEntrada (A não ser é claro pelas colunas das tabelas).

DROP FUNCTION getDataUltBalanco;
DELIMITER //
CREATE FUNCTION getDataUltBalanco() RETURNS DATE
BEGIN
     DECLARE dataInicial DATE;
     /* O HANDLER ALTERADO */
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET dataInicial = CONCAT(YEAR(CURDATE()),'/01/01');
    
     SELECT BalancoData INTO dataInicial
           FROM tab_Balancos
           WHERE BalancoID = (SELECT MAX(BalancoID) FROM tab_Balancos);
    
     RETURN dataInicial;
END//
DELIMITER ;
 
DROP FUNCTION getQtdBalanco;
DELIMITER //
CREATE FUNCTION getQtdBalanco(produto INTEGER) RETURNS DOUBLE
BEGIN
     DECLARE qtdBalanco DOUBLE;
     /* O HANDLER ALTERADO */
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET qtdBalanco = IFNULL(qtdBalanco,0);
     SELECT SUM(BI.BalancoItem_Quantidade) INTO qtdBalanco
           FROM tab_Balancos B, tab_BalancosItens BI
           WHERE BI.BalancoItem_BalancoID = B.BalancoID AND
                B.BalancoID = (SELECT MAX(balancoid) FROM tab_balancos) AND
                BI.BalancoItem_ProdutoID = produto
           GROUP BY BI.balancoItem_ProdutoID;
          
    RETURN qtdBalanco;          
    
END//
DELIMITER ;
 
DROP FUNCTION getQtdEntrada;
DELIMITER //
CREATE FUNCTION getQtdEntrada(produto INTEGER, dataInicial DATE) RETURNS DOUBLE
BEGIN
     DECLARE qtdEntrada DOUBLE;
     /* O HANDLER ALTERADO */
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET qtdEntrada = IFNULL(qtdEntrada,0);
    
     SELECT SUM(EI.EntradaItem_Quantidade) INTO qtdEntrada
           FROM tab_Entradas E, tab_EntradasItens EI
           WHERE EI.EntradaItem_EntradaID = E.EntradaID AND
                E.EntradaData >= dataInicial AND
                EI.EntradaItem_ProdutoID = produto
           GROUP BY EI.EntradaItem_ProdutoID;
          
     RETURN qtdEntrada;
    
END//
DELIMITER ;
 
DROP FUNCTION getQtdSaida;
DELIMITER //
CREATE FUNCTION getQtdSaida(produto INTEGER, dataInicial DATE) RETURNS DOUBLE
BEGIN
     DECLARE qtdSaida DOUBLE;
     /* O HANDLER ALTERADO */
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET qtdSaida = IFNULL(qtdSaida,0);
     SELECT SUM(SI.SaidaItem_Quantidade) INTO qtdSaida
           FROM tab_Saidas S, tab_SaidasItens SI
           WHERE SI.SaidaItem_SaidaID = S.SaidaID AND
                S.SaidaData >= dataInicial AND
                SI.SaidaItem_ProdutoID = produto
           GROUP BY SI.SaidaItem_ProdutoID;
          
     RETURN qtdSaida;
END//
DELIMITER ;
 
DROP FUNCTION getQtdVenda;
DELIMITER //
CREATE FUNCTION getQtdVenda(produto INTEGER, dataInicial DATE) RETURNS DOUBLE
BEGIN
     DECLARE qtdVenda DOUBLE;
     /* O HANDLER ALTERADO */
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET qtdVenda = IFNULL(qtdVenda,0);
    
     SELECT SUM(VI.VendaItem_Quantidade) INTO qtdVenda
           FROM tab_Vendas V, tab_VendasItens VI
           WHERE VI.VendaItem_VendaID = V.VendaID AND
                V.VendaData >= dataInicial AND
                VI.VendaItem_ProdutoID = produto
           GROUP BY VI.VendaItem_ProdutoID;
          
     RETURN qtdVenda;
END//
DELIMITER ;
 
 Finalmente os triggers. Nos triggers eu chamei as funções para retornar os valores que estas se destinam a retornar (dahhh, descobri isto sozinho, *risos*), armazenei os valores em variaveis, depois é só atualizar o saldo do estoque do produto onde:
 
      saldo = (qtdBalancos + qtdEntradas) - (qtdSaidas + qtdVendas).
     
 Note que no código dos triggers a única diferença será o ID do produto que se deseja atualizar, e o código do balanço pode ser aplicado para os triggers de entradas, saídas e vendas. Sendo assim para não repetir o código este pode ser encapsulado em um procedimento, por exemplo, setAtualizaEstoque(produto:inteiro). Assim o trigger só precisaria do codigo:
 
      CALL setAtualizaEstoque(<ID_do_produto>);
 
 Pela lógica, deve funcionar, mas não testei. Então vamos ao código dos triggers.
 
--TRIGGERS DA TABELA DE BALANCOS
DROP TRIGGER tab_Balancos_Deleta;
DELIMITER //
CREATE TRIGGER tab_Balancos_Deleta BEFORE DELETE ON tab_Balancos FOR EACH ROW
BEGIN
     DELETE FROM tab_BalancosItens WHERE BalancoItem_BalancoID = OLD.BalancoID;
    
END//
DELIMITER ;
 
--TRIGGERS DA TABELA DE ITENS DE BALANCOS
DROP TRIGGER tab_BalancosItens_InsereSaldoProduto;
DELIMITER //
CREATE TRIGGER tab_BalancosItens_InsereSaldoProduto AFTER INSERT ON tab_BalancosItens FOR EACH ROW
BEGIN
     DECLARE dataInicial DATE;
     DECLARE qtdBalancos, qtdEntradas, qtdSaidas, qtdVendas DOUBLE;
     SET dataInicial = getDataUltBalanco();
     SET qtdBalancos = getQtdBalanco(NEW.BalancoItem_ProdutoID);
     SET qtdEntradas = getQTdEntrada(NEW.BalancoItem_ProdutoID,dataInicial);
     SET qtdSaidas = getQtdSaida(NEW.BalancoItem_ProdutoID,dataInicial);
     SET qtdVendas = getQtdVenda(NEW.BalancoItem_ProdutoID,dataInicial);    
    
     UPDATE tab_Produtos SET ProdutoSaldoEstoque = (qtdBalancos + qtdEntradas) -
           (qtdSaidas + qtdVendas) WHERE ProdutoID = NEW.BalancoItem_ProdutoID;
    
END//
DELIMITER ;
 
DROP TRIGGER tab_BalancosItens_AtualizaSaldoProduto;
DELIMITER //
CREATE TRIGGER tab_BalancosItens_AtualizaSaldoProduto AFTER UPDATE ON tab_BalancosItens FOR EACH ROW
BEGIN
     DECLARE dataInicial DATE;
     DECLARE qtdBalancos, qtdEntradas, qtdSaidas, qtdVendas DOUBLE;
     SET dataInicial = getDataUltBalanco();
     SET qtdBalancos = getQtdBalanco(NEW.BalancoItem_ProdutoID);
     SET qtdEntradas = getQTdEntrada(NEW.BalancoItem_ProdutoID,dataInicial);
     SET qtdSaidas = getQtdSaida(NEW.BalancoItem_ProdutoID,dataInicial);
     SET qtdVendas = getQtdVenda(NEW.BalancoItem_ProdutoID,dataInicial);    
    
     UPDATE tab_Produtos SET ProdutoSaldoEstoque = (qtdBalancos + qtdEntradas) -
           (qtdSaidas + qtdVendas) WHERE ProdutoID = NEW.BalancoItem_ProdutoID;
    
END//
DELIMITER ;
 
DROP TRIGGER tab_BalancosItens_DeletaSaldoProduto;
DELIMITER //
CREATE TRIGGER tab_BalancosItens_DeletaSaldoProduto AFTER DELETE ON tab_BalancosItens FOR EACH ROW
BEGIN
     DECLARE dataInicial DATE;
     DECLARE qtdBalancos, qtdEntradas, qtdSaidas, qtdVendas DOUBLE;
     SET dataInicial = getDataUltBalanco();
     SET qtdBalancos = getQtdBalanco(OLD.BalancoItem_ProdutoID);
     SET qtdEntradas = getQTdEntrada(OLD.BalancoItem_ProdutoID,dataInicial);
     SET qtdSaidas = getQtdSaida(OLD.BalancoItem_ProdutoID,dataInicial);
     SET qtdVendas = getQtdVenda(OLD.BalancoItem_ProdutoID,dataInicial);    
    
     UPDATE tab_Produtos SET ProdutoSaldoEstoque = (qtdBalancos + qtdEntradas) -
           (qtdSaidas + qtdVendas) WHERE ProdutoID = OLD.BalancoItem_ProdutoID;
    
END//
DELIMITER ;
 
 Bom então é isso. Foi assim que resolvi meu problema.
 
 A mesma lógica também pode ser utilizada para atualizar o valor de uma conta a receber, o valor de uma determinada venda atibuído ao caixa, por exemplo. Isto é útil para diminuir a necessidade do programador abrir o arquivo fonte, modificá-lo e depois compilar, depois atualizar no cliente, além da portabilidade, se mudar a linguagem de programação o código de atualização do estoque permanece o mesmo, já que este é armazenado no próprio banco de dados.
 Obrigado e até a próxima.
     
Página(s): 1/1    


Seu Nome:

Seu eMail:

ALTERAR PARA MODO HTML
Mensagem:

[:)] = 
[:P] = 
[:(] = 
[;)] = 

HTML DESLIGADO

     
 VOLTAR

  



CyberWEB Network Ltda.    © Copyright 2000-2025   -   Todos os direitos reservados.
Powered by HostingZone - A melhor hospedagem para seu site
Topo da página