Trigger Baixa estoque

16/10/2018

0

Boa pessoal pessoal,

estou criando uma trigger em Oracle, que ao realizar uma venda (insert ou update), a trigger retire a quantidade vendida do estoque. Porém, estou com alguma dificuldades.

A trigger criada é a seguinte:
CREATE OR REPLACE TRIGGER BAIXA_ESTOQUE
AFTER UPDATE OR INSERT ON ITEMPEDIDO
FOR EACH ROW
DECLARE IDPEDIDO INT;
BEGIN
SELECT IDPEDIDO INTO IDPEDIDO FROM PEDIDO WHERE IDPEDIDO = :NEW.IDPEDIDO;
IF (IDPEDIDO > :NEW.IDPEDIDO) THEN
UPDATE PRODUTO SET QUANTIDADE = QUANTIDADE - :NEW.QUANTIDADE
WHERE IDPRODUTO = :NEW.IDPRODUTO;
END IF;
END;

Realizo o insert na tabela itempedido, porém quando vou verificar no select * from produto, a quantidade não foi modificada.

Conseguem me ajudar onde estou errando ?
Caique

Caique

Responder

Post mais votado

17/10/2018

Bom dia,

Porque vc cria uma trigger para insert e outra para update, ficaria mais simples...

Se ainda assim na trigger de update o camando "update produto set quantidade = quantidade - :new.quantidade...." não funcionar... tente assim:
"update produto set quantidade = :old.quantidade - :new.quantidade...."

Não tenho oracle para testar no momento, mas acho q por esse caminho vai funcionar...

abraço



Ricardo Pestana

Ricardo Pestana
Responder

Mais Posts

17/10/2018

Emerson Nascimento

tente algo assim:
CREATE OR REPLACE TRIGGER BAIXA_ESTOQUE
AFTER UPDATE OR INSERT ON ITEMPEDIDO
FOR EACH ROW
BEGIN
	IF INSERTING THEN
		UPDATE PRODUTO SET QUANTIDADE = QUANTIDADE - :NEW.QUANTIDADE 
		WHERE IDPRODUTO = :NEW.IDPRODUTO;
	ELSE
		UPDATE PRODUTO SET QUANTIDADE = QUANTIDADE - (:NEW.QUANTIDADE - :OLD.QUANTIDADE)
		WHERE IDPRODUTO = :NEW.IDPRODUTO;
	END IF;
END;

Note que o tratamento para alteração do pedido é diferente, pois se você alterasse a quantidade de 5 para 10, da forma que estava seriam subtraídas, ao todo, 15 unidades.
Responder

17/10/2018

Caique

Obrigado pelo retorno, realmente da forma que mencinou está correto.

Porém descobri um outro problema... A trigger é criada com sucesso, porém ao realizar um teste, fazendo um insert na tabela ITEMPEDIDO, é apresentada a mensagem: ORA-02291: restrição de integridade (SYSTEM.FK_IDPEDIDO) violada - chave mãe não localizada.

A coluna IDPEDIDO é uma PK da tabela PEDIDO e creio que o motivo do erro é que primeiramente deve-se inserir o registro na tabela PEDIDO antes de fazer o insert na ITEMPEDIDO.

Fiz um teste com a trigger abaixo mas é apresentada a mensagem:
3/48 PLS-00049: variável de ligação 'NEW.IDCLIENTE' inválida
3/64 PLS-00049: variável de ligação 'NEW.DATAPEDIDO' inválida

CREATE OR REPLACE TRIGGER BAIXA_ESTOQUE
AFTER UPDATE OR INSERT ON ITEMPEDIDO
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO PEDIDO VALUES (:NEW.IDPEDIDO, :NEW.IDCLIENTE, :NEW.DATAPEDIDO, :NEW.VALOR);
IF INSERTING THEN
UPDATE PRODUTO SET QUANTIDADE = QUANTIDADE - :NEW.QUANTIDADE
WHERE IDPRODUTO = :NEW.IDPRODUTO;
ELSE
UPDATE PRODUTO SET QUANTIDADE = QUANTIDADE - (:NEW.QUANTIDADE - :OLD.QUANTIDADE)
WHERE IDPRODUTO = :NEW.IDPRODUTO;
END IF;
END IF;
END;

Sabem como resolver essa questão ?

Muito obrigado por enquanto.
Responder

17/10/2018

Emerson Nascimento

O pedido foi incluído, o banco de dados está incluindo os itens, e daí você tenta incluir o pedido novamente? porque disso???
IF INSERTING THEN
INSERT INTO PEDIDO VALUES (:NEW.IDPEDIDO, :NEW.IDCLIENTE, :NEW.DATAPEDIDO, :NEW.VALOR);

o trecho acima é totalmente desnecessário e nem faz sentido.
Responder

17/10/2018

Caique

Existem 2 tabelas, uma é a PEDIDO, no qual está as informações do pedido, como por exemplo: id do pedido (PK), ID cliente, data do pedido e o valor total.

Outra é a tabela ITEMPEDIDO, onde está os registros: ID PEDIDO (FK PEDIDO), nºitem, Valor, Quantidade e ID Produto.

A trigger está correta, porém ao realizar um insert na tabela ITEMPEDIDO está exibindo a mensagem:
ORA-02291: restrição de integridade (SYSTEM.FK_IDPEDIDO) violada - chave mãe não localizada.

Creio que o motivo seja porque na tabela PEDIDO, ainda não existe o IDPEDIDO (FK) que está sendo inserindo no insert: insert into itempedido values (7,3,1300.33,3,2).

Ou seja, primeiramente o registro IDPEDIDO, deve constar na tabela PEDIDO, antes de ser inserido na tabela ITEMPEDIDO.

O trecho abaixo, é aonde estou tentando primeiramente fazer o insert na tabela PEDIDO através da trigger, antes mesmo de realizar o insert na tabela ITEMPEDIDO.



 IF INSERTING THEN
     INSERT INTO PEDIDO VALUES (:NEW.IDPEDIDO, :NEW.IDCLIENTE, :NEW.DATAPEDIDO, :NEW.VALOR);
Responder

09/04/2020

Jose Melo

USANDO A DICA ACIMA FUNCIONOU AQUI CERTINHO:

/* DA BAIXA NO ESTOQUE */
CREATE OR REPLACE TRIGGER BAIXA_ESTOQUE
AFTER UPDATE OR INSERT ON ITEM_VENDA
FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE PRODUTO SET ESTOQUE = ESTOQUE - :NEW.QTDE
WHERE ID_PRODUTO = :NEW.ID_PRODUTO;
ELSE
UPDATE PRODUTO SET ESTOQUE = ESTOQUE - (:NEW.QTDE - :OLD.QTDE)
WHERE ID_PRODUTO = :NEW.ID_PRODUTO;
END IF;
END;

/* AQUI ATUALIZA O ESTOQUE TODA VEZ QUE INSIRO UM REGISTRO EM ITEM_COMPRA*/
CREATE OR REPLACE TRIGGER ATUALIZA_ESTOQUE
AFTER UPDATE OR INSERT ON ITEM_COMPRA
FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE PRODUTO SET ESTOQUE = ESTOQUE + :NEW.QTDE
WHERE ID_PRODUTO = :NEW.ID_PRODUTO;
ELSE
UPDATE PRODUTO SET ESTOQUE = ESTOQUE + (:NEW.QTDE + :OLD.QTDE)
WHERE ID_PRODUTO = :NEW.ID_PRODUTO;
END IF;
END;
Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar