web-dev-qa-db-fra.com

Créer un déclencheur qui met à jour une colonne sur une table lorsqu'une colonne d'une autre table est mise à jour

j'ai deux tables

Commande (identifiant, date, note)

et

Livraison (Id, Note, Date)

Je veux créer un déclencheur qui met à jour la date dans la livraison lorsque la date est mise à jour dans la commande.

Je pensais faire quelque chose comme 

CREATE OR REPLACE TRIGGER your_trigger_name
BEFORE UPDATE
ON Order
DECLARE
BEGIN
   UPDATE Delivery set date = ??? where id = ???
END;

Comment puis-je obtenir la date et l'identifiant de la ligne?

merci

14
GigaPr

Comment puis-je obtenir la date et l'identifiant de la ligne?

En supposant qu'il s'agisse de colonnes de votre table ORDER appelée DELIVERY_DATE et que votre déclencheur devrait ressembler à ceci:

CREATE OR REPLACE TRIGGER your_trigger_name
    BEFORE UPDATE ON Order
    FOR EACH ROW 
BEGIN
   if :new.delivery_date != :old.delivery_date
   then
       UPDATE Delivery d
       set d.delivery_date = :new.delivery_date
       where d.order_id = :new.id;
    end if;
END;

Notez la clause FOR EACH ROW: nécessaire pour référencer les valeurs de lignes individuelles. J'ai utilisé une construction IF pour tester s'il fallait exécuter UPDATE à la livraison. Si vous n'avez aucune autre logique dans votre déclencheur, vous pouvez l'écrire comme ceci ...

CREATE OR REPLACE TRIGGER your_trigger_name
    BEFORE UPDATE OF delivery_date ON Order
    FOR EACH ROW 
BEGIN
   UPDATE Delivery d
   set d.delivery_date = :new.delivery_date
   where d.order_id = :new.id;
END;

J'ai répondu à la question que vous avez posée mais, en passant, je soulignerai que votre modèle de données est sous-optimal. Une conception correctement normalisée retiendrait DELIVERY_DATE sur une seule table: DELIVERY semble la place logique qui lui est réservée.

16
APC

Lorsque vous avez besoin de ce type de déclencheur, examinez bien votre conception. Un enregistrement de livraison séparé est-il vraiment nécessaire? Une commande a-t-elle réellement plus d'une livraison? 

Les déclencheurs semblent agréables mais ils ont tendance à gâcher les choses assez rapidement.

0
Rene

Il existe une référence implicite, nouvelle et ancienne, dans le déclencheur sous la forme de: REFERENCING ANCIENNE ANCIENNE NOUVELLE NEUVE

Vous pouvez écrire dans la valeur: NEW mais pas dans la valeur: OLD.

UPDATE Delivery set date = :new.delivery_date where id = :new.id;


CREATE OR REPLACE TRIGGER "BUR_TABLENAME" BEFORE
UPDATE ON "TABLE" FOR EACH ROW
BEGIN
  If :new.active_date is not null Then
    :new.active_date := TRUNC(:new.active_date);
End If;
END;

Modèle:

CREATE OR REPLACE TRIGGER TRIGGER_NAME
 BEFORE
 UPDATE
 ON TABLE_NAME
 REFERENCING OLD AS OLD NEW AS NEW
 FOR EACH ROW
DECLARE
   V_VARIABLE   NUMBER (1);
BEGIN
   //Do Stuff;
  null;
end;
0
Brian

Utilisez les variables de liaison OLD et NEW. OLD fait référence à la ligne ou à la colonne en cours de mise à jour avant la modification; NEW le référence après le changement.

CREATE OR REPLACE TRIGGER trig1
    BEFORE UPDATE
    ON order  REFERENCING NEW AS new
    FOR EACH ROW
BEGIN
    UPDATE delivery
       SET ddate   = :new.ddate
     WHERE id = :new.id;
END;

Vous pouvez modifier la clause REFERENCING pour attribuer différents noms à vos variables de liaison. Vous pouvez également inclure OLD as <name>. Exemple:

CREATE OR REPLACE TRIGGER trig1
    BEFORE UPDATE
    ON order REFERENCING OLD AS old_values NEW AS new_values
    ...

Si vous ne souhaitez pas modifier les noms par défaut "ancien" et "nouveau", vous pouvez supprimer complètement la clause REFERENCING.

0
Igby Largeman