Trigger Baixa estoque

SQL

Oracle

16/10/2018

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

Curtidas 0

Melhor post

Ricardo Pestana

Ricardo Pestana

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



GOSTEI 1

Mais Respostas

Emerson Nascimento

Emerson Nascimento

16/10/2018

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.
GOSTEI 1
Caique

Caique

16/10/2018

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.
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

16/10/2018

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.
GOSTEI 0
Kevlyn Godoy

Kevlyn Godoy

16/10/2018

Olá Concurseiros


Venha participar do Aniversário do Maior Site de Rateios do Brasil,

O aniversário é do Concurseiros Unidos,
mas o presente quem ganha é você!

Desconto de 30% a 70% em todo o site!
Corre aproveitar antes que termine!
5541991115296
GOSTEI 0
Caique

Caique

16/10/2018

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);
GOSTEI 0
Jose Melo

Jose Melo

16/10/2018

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;
GOSTEI 0
POSTAR