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

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

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

Aceitar