Wertzuweisung zu einer Stringvariablen als Teil eines records

Hallo,

ich möchte eine Funktion erstellen, die bestimmte Berechnungen durchführt. Dazu soll zuerst geprüft werden, ob die Berechnung möglich ist. Wenn nicht, soll eine entsprechende Fehlermeldung zurückgegeben werden. Ich habe mir das so gedacht, dass als Ergebnis ein Record zurückgegeben wir, in dem an erster Position der berechnete Wert steht (oder NULL, wenn die Berechnung nicht möglich war) und an zweiter Position eine Fehlermeldung (oder NULL, wenn alles gut ging).

Es folgt der Code für die Funktion

CREATE OR REPLACE FUNCTION fn_DFG298_CGHF(IN sTable varchar, IN sPCon varchar, OUT icvalue numeric, OUT icmessage varchar) RETURNS record AS
$$declare
    -- sTable = table for which function is called
    -- sPCon  = phase constituent for which DFG298 shall be calculated
    qrec record;
    nDFH298 numeric;
    nS298 numeric;
    nS298H2 numeric;
    ntemp numeric;
    nCharge numeric;     -- Integers divided by i (i>1) give zero and lead to miscalculation in Gibbs-Helmholtz equation. Therefore, charge must be of type numeric

begin
    -- check if calculation is possible
    -- DFH298 present?
    execute 'select value from ' || sTable || ' where pcon = ''' || sPCon || ''' and datatype = ''DFH298''' into nDFH298;
    -- S298 present?
    execute 'select value from ' || sTable || ' where pcon = ''' || sPCon || ''' and datatype = ''S298''' into nS298;
    -- are all S298 for constituting elements present?
    for qrec in select pconcomposition.element, pconcomposition.numberofelement as a, element.stoichiometriccoefficient as b, element.s298 as c from pconcomposition, element where pconcomposition.pcon = sPCon and pconcomposition.element = element.symbol loop
        if qrec.c is NULL then -- at least one S298 value is missing
            select NULL into ntemp;
            exit
        end if;    
    end loop;  
    if (nDFH298 is NULL) or (nS298 is NULL) or (ntemp is NULL) then ------ HIER
        if (nDFH298 is NULL) then
            icMessage := 'DFH298 missing ';
        end if;
        if (nS298 is NULL) then
            icMessage := icMessage || 'S298 missing ';
        end if;    
        if (ntemp is NULL) then
            icMessage := icMessage || 'at least one S298 for constituting elements is missing';
        end if;
        icvalue := NULL;
        -- icMessage := 'mm';
        return;
        exit;
    end if;
    -- calculation is possible
    select charge into nCharge from pcon where symbol = sPCon;
    -- first step
    select sum(a*c/b) into ntemp from (select pconcomposition.element, pconcomposition.numberofelement as a, element.stoichiometriccoefficient as b, element.s298 as c from pconcomposition, element where pconcomposition.pcon = sPCon and pconcomposition.element = element.symbol) as foo;    
    -- second step
    if nCharge <> 0 then
        select (ntemp-(a*c/b)) from (select pconcomposition.element, pconcomposition.numberofelement as a, element.stoichiometriccoefficient as b, element.s298 as c from pconcomposition, element where pconcomposition.pcon = sPCon and pconcomposition.element = element.symbol and pconcomposition.element ='EA') as foo into ntemp;
    end if;        
    select S298 into nS298H2 from element where symbol = 'H';
    icvalue := nDFH298-298.15*(nS298+(nCharge/2)*nS298H2-ntemp);
    icmessage := NULL;
    return;
end;$$
  LANGUAGE 'plpgsql';

An der mit HIER gekennzeichneten Stelle beginnt die Erstellung der Fehlermeldung. Das Problem ist nun, dass als Ergebnis immer NULL zurückkommt, obwohl der Variablen icMessage eigentlich ein Wert zugewiesen werden müsste (ich weiß dies aus raise notice Meldungen). Wenn ich der Variablen einen Wert “zu Fuß” übergebe (im Beispiel auskommentiert: icMessage := ‘mm’), dann kommt der Wert auch auf der Kommandozeie raus.

Ein ähnliches Problem habe ich auch weiter unten; wenn keine Fehlermeldung generiert wird, wird auch der Ergebnisvariablen icvalue kein Wert zugewiesen.

Irgendwas Grundätzliches mache ich hier wohl falsch, aber was?

Eremit

Ich habe es gefunden. Vor den Wertzuweisungen musste die Variable stemp initialisiert werden mit

stemp := ‘’;

Eremit

Wäre es nicht besser, an dieser Stelle eine Exception zu werfen, die dann vom Backend abgefangen und entsprechend behandelt wird?

Negativ, die Routine darf nicht abgebrochen werden. Fehlermeldungen werden in die Datenbank geschrieben.
Aber ich habe das Problem in der Zwischenheit wie gesagt gelöst. Trotzdem vielen Dank.
Eremit