Trigger Baixa estoque
16/10/2018
0
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
Post mais votado
17/10/2018
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
Mais Posts
17/10/2018
Emerson Nascimento
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.
17/10/2018
Caique
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.
17/10/2018
Emerson Nascimento
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.
17/10/2018
Caique
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);
09/04/2020
Jose Melo
/* 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;
Clique aqui para fazer login e interagir na Comunidade :)