2016-08-30 5 views
1

Ich habe zwei Funktionen, die den guten Wert zurückgeben. Aber wenn ich diese Funktionen innerhalb eines Triggers aufrufen, geben sie immer 0 statt des guten Wertes zurück.Funktion gibt schlechten Wert innerhalb eines Triggers zurück

Der Rückgabetyp dieser Funktionen ist real. Die direkte und dramatische Konsequenz ist, dass der Trigger falsche Werte in Tabellen einfügt, wenn er aufgerufen wird.

Die Funktion:

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' ; 

Die Triggerfunktion (zum Testen geändert!):

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' ; 

Die Trigger-Definition:

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

Ohne Code: Nein. –

+0

Ich habe einen Auszug aus dem Code, den ich verwende. –

+0

Sie ändern nichts in der Triggerfunktion. Sie ordnen diesen Wert nur einer lokalen Variablen zu, aber Sie ändern den Datensatz 'NEW' nicht. –

Antwort

1

Die präsentierten Code funktionieren sollte.

Es ist besonders merkwürdig, dass Sie 0 als Ergebnis zu sehen. Wenn in remaining_absence_day keine übereinstimmende Zeile gefunden wird, wird NULL angezeigt, nicht 0. Aber wenn Sie die Funktion mit den gleichen Parametern in derselben Umgebung aufrufen, sollten Sie am Anfang dasselbe Ergebnis sehen.

Die verbleibende mögliche Erklärung, die ich denken kann: Verwirrung mit dem Schemasuchpfad. Wie: Sie haben eine zweite Instanz der Funktion get_remaining_hour() oder die Tabelle remaining_absence_day in einem anderen Schema. Und Sie rufen die Funktion mit einer anderen Einstellung für search_path auf. Haben Sie Ihren Vergleich in derselben Sitzung durchgeführt?

Oder, da man mit einem AFTER Trigger arbeiten: es könnte andere Auslöser sein auf dem Tisch absence, die die Tabelle remaining_absence_day, zu modifizieren, die vor Ihre Trigger ausgelöst werden.

Alle anderen Änderungen, die ich vorgenommen habe, sind kosmetischer Natur oder geringfügiger Vereinfachungen.

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

Vielen Dank, Sie hatten Recht, als Sie sagten: "Oder, da Sie mit einem AFTER-Trigger arbeiten: Es kann andere Trigger auf Tisch Abwesenheit geben, die die Tabelle resting_absence_day ändern, die vor Ihrem Auslöser ausgelöst werden . " Beim Debugging der Tabelle wurde ein Trigger ausgelöst, der sich auf den neuen Trigger auswirkt. Vielen Dank für Ihre Hilfe. –

Verwandte Themen