2016-08-30 4 views
1

J'ai deux fonctions qui retournent la bonne valeur. Mais quand j'appelle ces fonctions à l'intérieur d'un déclencheur, elles retournent toujours 0 au lieu de la bonne valeur.Fonction renvoie une valeur incorrecte à l'intérieur d'un déclencheur

Le type de retour de ces fonctions est real. La conséquence directe et dramatique est que le déclencheur insère des valeurs erronées dans les tables lorsqu'il est appelé.

La fonction:

create or replace function get_remaining_hour(id_user_v integer,id_absence_v_type integer,id_year_v integer) returns real as 
$BODY$ 
BEGIN 
    return (select sum(number_hour) 
      from remaining_absence_day 
      where id_user= $1 
       and id_absence_type=$2 
       and id_year=$3); 
END; 
$BODY$ 
LANGUAGE 'plpgsql' ; 

La fonction de déclenchement (modifié pour le test!):

create OR REPLACE function update_absence() returns TRIGGER AS 
$BODY$ 
DECLARE 
    old_number_hour real; 
BEGIN 
    old_number_hour:=get_remaining_hour(3,2,8); 
    insert into debugging(col,val) values('old_number_hour', old_number_hour); 
    return null; 
END; 
$BODY$ 
LANGUAGE 'plpgsql' ; 

La définition de déclenchement:

drop trigger if exists update_absence on absence; 
CREATE TRIGGER update_absence 
    after update of type,duration_hour,duration_day on absence 
    for each ROW 
    execute procedure update_absence(); 
+4

Sans code: aucun. –

+0

J'ai ajouté un extrait du code que j'utilise. –

+0

Vous ne modifiez rien dans la fonction de déclenchement. Vous n'attribuez cette valeur qu'à une variable locale, mais vous ne modifiez pas l'enregistrement 'NEW'. –

Répondre

1

Le code présenté devrait fonctionner.

Il est particulièrement étrange que vous voyez 0 comme résultat. Si aucune ligne correspondante n'est trouvée dans remaining_absence_day, vous verrez NULL, et non 0. Mais si vous appelez la fonction avec les mêmes paramètres dans le même environnement, vous devriez voir le même résultat pour commencer.

La dernière explication possible que je peux penser à: confusion avec le schéma de recherche de schéma. Comme: vous avez une deuxième instance de la fonction get_remaining_hour() ou la table remaining_absence_day dans un schéma différent. Et vous appelez la fonction avec un réglage différent pour search_path. Avez-vous exécuté votre comparaison dans la même session?

Ou, puisque vous travaillez avec un AFTER déclencheur: il pourrait y avoir d'autres éléments déclencheurs sur la table absence qui modifient la table remaining_absence_day, qui a tiré avant votre déclencheur.

Toutes les autres modifications que j'ai apportées sont de nature cosmétique ou de simplifications mineures.

CREATE OR REPLACE FUNCTION get_remaining_hour(id_user_v int 
              , id_absence_v_type int 
              , id_year_v int) 
    RETURNS real AS 
$func$ 
BEGIN 
    RETURN (
    SELECT sum(number_hour) 
    FROM remaining_absence_day -- referencing the right table? see search_path 
    WHERE id_user   = $1 
    AND id_absence_type = $2 
    AND id_year   = $3 
    ); 
END 
$func$ LANGUAGE plpgsql STABLE; -- don't quote the language name 

CREATE OR REPLACE FUNCTION update_absence() 
    RETURNS TRIGGER AS 
$func$ 
BEGIN 
    INSERT INTO debugging(col, val) 
    VALUES('old_number_hour', get_remaining_hour(3,2,8)); -- hard coded only for testing? 
    RETURN null; -- only good for AFTER trigger 
END 
$func$ LANGUAGE plpgsql; 

DROP TRIGGER IF EXISTS update_absence ON absence; 
CREATE TRIGGER update_absence 
AFTER UPDATE OF type, duration_hour, duration_day ON absence 
FOR EACH ROW EXECUTE PROCEDURE update_absence(); 
+0

Merci beaucoup, vous aviez raison quand vous avez dit: "Ou, puisque vous travaillez avec un déclencheur AFTER: il peut y avoir d'autres déclencheurs sur la table d'absence qui modifient la table remaining_absence_day, qui sont déclenchés avant votre trigger " Il y avait un déclencheur déclenché sur le débogage de table qui a interféré avec mon nouveau déclencheur. Merci à tous pour votre aide. –