2017-03-19 3 views
1

J'écris une fonction trigger dans PostgreSQL 9.5. Lorsqu'une colonne nommée action_flag est mise à jour de FALSE à TRUE, une fonction est appelée. Si order_num est dans une table, alors je veux la mise à jour de FALSE à TRUE pour continuer. Sinon, si order_num est dans une autre table, je souhaite déclencher une exception et empêcher la mise à jour de se produire.Mise à jour d'une colonne dans une fonction en utilisant plpgsql

J'ai besoin d'aide pour écrire le UPDATE dans ma déclaration IF. La partie ELSEIF fonctionne comme prévu.

CREATE OR REPLACE FUNCTION check_ingredient_availability() 
RETURNS TRIGGER AS 
$Body$ 
BEGIN 
    if (OLD.order_num IN (SELECT order_num 
        FROM can_prep_m_orders)) THEN 
     RAISE NOTICE 'This is a notice.'; 
     --UPDATE meal_order 
     --SET actioned_flag=TRUE 
     --WHERE order_num=OLD.order_NUM; 

     --EXECUTE 'UPDATE meal_order 
      -- SET actioned_flag=TRUE 
      --WHERE  order_num=$1' 
      --USING OLD.order_num; 
     RETURN NULL; 
    ELSEIF (OLD.order_num IN (SELECT order_num 
         FROM cannot_prep_m_orders)) THEN 
     RAISE EXCEPTION 'Missing ingredients. Cannot prepare order number %.', 
       OLD.order_num; 
     RETURN NULL; 
    ELSE 
     RETURN NULL; 
    END IF; 
END;  
$Body$ LANGUAGE plpgsql; 

Répondre

0

Utilisation EXISTS:

CREATE OR REPLACE FUNCTION check_ingredient_availability() 
    RETURNS TRIGGER AS 
$func$ 
BEGIN 
    IF EXISTS (
     SELECT 1 FROM can_prep_m_orders 
     WHERE order_num = NEW.order_num -- NEW !? 
     ) THEN 
     RAISE NOTICE 'This is a notice.'; 

     -- do nothing, let original UPDATE proceed 

     RETURN NEW; -- let UPDATE proceed 
    END IF; 

    IF EXISTS (
     SELECT 1 FROM cannot_prep_m_orders 
     WHERE order_num = NEW.order_num -- NEW!? 
     ) THEN 

     RAISE EXCEPTION 'Missing ingredients. Cannot prepare order number %.', NEW.order_num; 
             -- I assume you want to mention the *new* order_num? 
    END IF; 

    RETURN NULL; -- cancel original UPDATE in all other cases 
END 
$func$ LANGUAGE plpgsql; 

connexes:

En outre, ajouter une clause WHEN à votre déclencheur pour exécuter ces contrôles lorsque

action_flag est mis à jour de FALSE à TRUE

CREATE TRIGGER your_trigger_name 
BEFORE UPDATE ON your_table 
FOR EACH ROW 
WHEN (NEW.action_flag AND NOT OLD.action_flag) 
EXECUTE procedure check_ingredient_availability(); 

connexes:

+0

Merci pour votre réponse, Erwin. C'était très utile! Je ne savais pas que RETURN NEW; est ce qui a permis à la mise à jour de continuer. – Pizzas

+0

@Pizzas: [Pensez à lire ce chapitre du manuel.] (Https://www.postgresql.org/docs/current/static/plpgsql-trigger.html) –