Triggers
[30 min]
Un ensemble de règles de gestion est défini afin de gérer le stock des produits du projet MediaTek. La politique suivante a été admise :
après chaque vente, la quantité vendue est soustraite de la quantité disponible indiquée dans une colonne de la table des produits,
si cette quantité (disponible) est inférieure à un "seuil" alors insérer un avertissement dans une table de journalisation avec la date du jour, le numéro de produit, et stock restant après mise à jour.
Question
Créer un déclencheur permettant de mettre à jour la quantité disponible dans la table produit à chaque insertion dans la table ligne facture (traitement du point 1).
Indice
CREATE TRIGGER TR_STOCK_AUDIT
BEFORE INSERT ON ligne_fact
Indice
Il s'agit d'un trigger qui cherche à faire une modification pour chaque insertion : utilisez un trigger "for each row".
FOR EACH ROW
Indice
Utilisez une requête update pour effectuer la mise à jour avec une condition sur le numéro de produit.
UPDATE ...SET ...WHERE num=:new.produit;Solution
CREATE TRIGGER TR_STOCK_AUDIT
BEFORE INSERT ON ligne_fact
FOR EACH ROW
BEGIN UPDATE PRODUIT p SET p.stock=p.stock - :new.qte WHERE p.num= :new.produit;END;/
Question
Testez votre trigger TR_STOCK_AUDIT en supprimant et en réinsérant les données des tables FACTURE et LIGNE_FACT.
Solution
delete from LIGNE_FACT;
delete from FACTURE;
-- INSERT INTO FACTURE, LIGNE_FACT-- Facture 1insert into FACTURE(num, client, date_etabli) values(
1, 2,to_date('20122000','DDMMYYYY')
);
insert into LIGNE_FACT(facture, produit, qte) values(
1, 1, 1);
insert into LIGNE_FACT(facture, produit, qte) values(
1, 2, 2);
-- Facture 2insert into FACTURE(num, client, date_etabli) values(
2, 2,to_date('01012001','DDMMYYYY')
);
insert into LIGNE_FACT(facture, produit, qte) values(
2, 1, 2);
insert into LIGNE_FACT(facture, produit, qte) values(
2, 3, 1);
insert into LIGNE_FACT(facture, produit, qte) values(
2, 2, 2);
-- Facture 3insert into FACTURE(num, client, date_etabli) values(
3, 2,to_date('17112004','DDMMYYYY')
);
insert into LIGNE_FACT(facture, produit, qte) values(
3, 1, 2);
insert into LIGNE_FACT(facture, produit, qte) values(
3, 2, 4);
insert into LIGNE_FACT(facture, produit, qte) values(
3, 3, 1);
-- Facture 4insert into FACTURE(num, client, date_etabli) values(
4, 3,to_date('14012004','DDMMYYYY')
);
insert into LIGNE_FACT(facture, produit, qte) values(
4, 2, 1);
insert into LIGNE_FACT(facture, produit, qte) values(
4, 3, 1);
-- Facture 5insert into FACTURE(num, client, date_etabli) values(
5, 4,to_date('19022004','DDMMYYYY')
);
insert into LIGNE_FACT(facture, produit, qte) values(
5, 1, 2);
insert into LIGNE_FACT(facture, produit, qte) values(
5, 3, 3);
insert into LIGNE_FACT(facture, produit, qte) values(
5, 2, 4);
-- Facture 6insert into FACTURE(num, client, date_etabli) values(
6, 4,to_date('17032004','DDMMYYYY')
);
insert into LIGNE_FACT(facture, produit, qte) values(
6, 1, 7);
insert into LIGNE_FACT(facture, produit, qte) values(
6, 2, 3);
insert into LIGNE_FACT(facture, produit, qte) values(
6, 3, 1);
commit;
select * from PRODUIT;
Question
Créer la table de journalisation.
Solution
CREATE TABLE audit_stock (
datealert DATE, produit NUMBER, stock NUMBER,CONSTRAINT FK_AUDIT_STOCK_PRODUIT FOREIGN KEY (produit) REFERENCES PRODUIT(num)
);
Question
Modifiez votre déclencheur de telle façon qu'après la mise à jour, il teste si le stock est inférieur à une valeur seuil de 5. Si le stock est inférieur à ce seuil, alors il devra insérer les informations adéquates dans la table de journalisation (traitement du point 2).
Solution
CREATE OR REPLACE TRIGGER TR_STOCK_AUDIT
BEFORE INSERT ON ligne_fact
FOR EACH ROW
DECLARE new_stock NUMBER; new_id NUMBER;BEGIN UPDATE PRODUIT p SET p.stock = p.stock - :new.qte WHERE p.num = :new.produit;SELECT stock INTO new_stock
FROM produit WHERE num = :new.produit;IF new_stock <= 5 THEN
INSERT INTO AUDIT_STOCK (datealert, produit, stock)
VALUES ( sysdate,:new.produit,
new_stock
);
END IF;
END;/
SHOW ERRORSQuestion
Testez à nouveau votre trigger jusqu'à obtenir au moins un message.
Solution
insert into FACTURE(num, client, date_etabli) values(
7, 2,to_date('20122000','DDMMYYYY')
);
insert into LIGNE_FACT(facture, produit, qte) values(
7, 1, 90);
select * from audit_stock;