Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Anderson Gaúcho

Atualização de estoque

Recommended Posts

Olá a todos,

 

Gostaria de trocar uma informação com a comunidade. Como vocês fazem para manter no banco uma tabela, por exemplo, de movimentação de estoque e além disso ainda manter a quantidade atual de estoque do produto? Tenho visto muita gente guardar a informação do estoque atual na tabela de produtos, mas não acho isso adequado.

Pensei em colocar o saldo atual na mesma tabela de movimentação, dado sendo gravado ao invés de calculado via select, para não pesar o processamento.

Mas para não quebrar (muito) a normalização, pensei em fazer a atualização deste campo via trigger.

No insert e no update normal, funcionou bem.

Segue a ideia básica:

 

Tabela Estoque:

CREATE TABLE `estoque` (
  `idMovEstoque` int(11) unsigned NOT NULL auto_increment,
  `idProduto` int(10) unsigned NOT NULL,
  `idFilial` int(10) unsigned NOT NULL,
  `Data` datetime NOT NULL,
  `TipoMov` char(1) collate latin1_general_ci default NULL,
  `Operacao` char(2) collate latin1_general_ci NOT NULL,
  `QtdeMov` decimal(12,4) default NULL,
  `idMovimento` int(10) unsigned default NULL,
  `SaldoEstoque` decimal(12,4) default NULL,
  PRIMARY KEY  (`idMovEstoque`),
  KEY `FK_estoque` (`idProduto`,`idFilial`,`Data`),
  KEY `FK_estoque1` (`idFilial`),
  CONSTRAINT `FK_estoque1` FOREIGN KEY (`idFilial`) REFERENCES `filiais` (`idFilial`),
  CONSTRAINT `FK_estoque2` FOREIGN KEY (`idProduto`) REFERENCES `produtos` (`idProduto`)
) ENGINE=InnoDB AUTO_INCREMENT=7774 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;

Triggers:

CREATE TRIGGER `AtualizaSaldoEstoqueInsercao` BEFORE INSERT ON `estoque` FOR EACH ROW BEGIN
	Declare SaldoAnterior Numeric(12,2);
	Select SaldoEstoque
		From Estoque
		Where (idFilial = New.idFilial) and (idProduto = New.idProduto)
		Order By idMovEstoque Desc
		Limit 0, 1
		Into SaldoAnterior;
	IF SaldoAnterior = NULL THEN
		SET SaldoAnterior = 0;
	END IF;
	IF New.TipoMov = 'E' THEN
		SET New.SaldoEstoque = SaldoAnterior + New.QtdeMov;
	ELSE
		SET New.SaldoEstoque = SaldoAnterior - New.QtdeMov;
	END IF;
END 

CREATE TRIGGER `AtualizaSaldoEstoqueAtualizacao` BEFORE UPDATE ON `estoque` FOR EACH ROW BEGIN
	Declare SaldoAnterior Numeric(12,2);
	Select SaldoEstoque
		From Estoque
		Where (idFilial = New.idFilial) and (idProduto = New.idProduto) and
			(idMovEstoque < New.idMovEstoque)
		Order By idMovEstoque Desc
		Limit 0, 1
		Into SaldoAnterior;
	IF SaldoAnterior = NULL THEN
		SET SaldoAnterior = 0;
	END IF;
	IF New.TipoMov = 'E' THEN
		SET New.SaldoEstoque = SaldoAnterior + New.QtdeMov;
	ELSE
		SET New.SaldoEstoque = SaldoAnterior - New.QtdeMov;
	END IF;
END

Até aí funcionou tudo bem.

O problema é que eu gostaria de, quando uma determiada linha da tabela Estoque fosse alterada, ou apagada, essa alteração se propagasse para todos os lançamentos de Estoque que foram feitos a partir desta linha, de forma recursiva. Daí em pensei em fazer uma nova trigger:

CREATE
	TRIGGER `AtualizaSaldoEstoqueAtualizacaoPos` AFTER UPDATE ON `estoque` 
	FOR EACH ROW BEGIN
		Update Estoque SET SaldoEstoque = 0
			Where (idProduto = New.idProduto) and
				(idFilial = New.idFilial) and
				(idMovEstoque > New.idMovEstoque)
		Limit 1;
	END;

E uma trigger semelhante para AFTER DELETE.

O objetivo deste último trigger é forçar o BEFORE UPDATE de todas as linhas subsequentes àquela que foi originalmente alterada, atualizando o campo SaldoEstoque.

Porém, o erro que ocorre quando tento atualizar uma linha (com update) é:

Can't update table 'estoque' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

gostaria de saber como você faz esse tipo de tratamento em MySQL.

 

Peço desculpas pelo tamanho do post :)

 

Um abraço

 

Anderson Gaúcho

Compartilhar este post


Link para o post
Compartilhar em outros sites

Antigamente, na empresa onde trabalhava, o controle do estoque faziamos combinando 3 tabelas: Entrada, Movimentação e Saída. Pela movimentação controlávamos se a saída já tinha sido efetivada ou não, porque todas as possíveis vendas de produtos geravam registros na tabela de saída e na tabela de movimento tinha uma flag que indicava o status da venda. Fica de sugestão para você bolar uma estrutura que controle isso. Ai o saldo é simples: Total de Entrada - Total de Saídas = Estoque do Produto.

 

[]'s

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.