0

次のストアドプロシージャがあります

CREATE FUNCTION runMortalityModel(a_user_id integer) RETURNS integer AS $$
DECLARE
    t1 RECORD;
    t2 RECORD;
    numberOfDeaths integer;
BEGIN
    SELECT person.id personId, person.age, condprobmin, condprobmax, random() experiment
    INTO t1
    FROM person, mortality_cond_prob 
    WHERE (user_id = a_user_id) and
    (person.age = mortality_cond_prob.age);

    SELECT personId
    INTO t2
    FROM t1
    WHERE (tmp.condprobmin <= experiment) and (experiment <= tmp.condprobmax);

    SELECT COUNT(*)
    INTO numberOfDeaths
    FROM t2;

    RAISE 'numberOfDeaths=%', numberOfDeaths;

    EXECUTE 
        'DELETE '
        || 'FROM person '
        || 'WHERE person.id IN ' 
        || t2;

    RETURN numberOfDeaths;
END
$$ LANGUAGE plpgsql;

を使用してこのストアドプロシージャを実行しようとすると

SELECT runMortalityModel(1);

エラーが発生しますRelation »t1« doesn't exist

どうすれば修正できますか?

更新1:ストアドプロシージャ宣言を次のように変更しました

CREATE OR REPLACE FUNCTION runMortalityModel(a_user_id integer) RETURNS integer AS $$
DECLARE
    t1 RECORD;
    t2 RECORD;
    numberOfDeaths integer;
BEGIN
    EXECUTE 'SELECT person.id personId, person.age, condprobmin, condprobmax, random()  experiment '    
    || 'FROM person, mortality_cond_prob '
    || 'WHERE (user_id = ' || a_user_id || ') and '
    || '(person.age = mortality_cond_prob.age)'
    INTO t1;

    EXECUTE 'SELECT personId '
    || 'FROM ' || t1
    || ' WHERE (tmp.condprobmin <= experiment) and (experiment <= tmp.condprobmax)'
    INTO t2;

    EXECUTE 'SELECT COUNT(*) ' 
    || 'FROM ' || t2
    INTO numberOfDeaths;

    RAISE 'numberOfDeaths=%', numberOfDeaths;

    EXECUTE 
        'DELETE '
        || 'FROM person '
        || 'WHERE person.id IN ' 
        || t2;

    RETURN numberOfDeaths;
END
$$ LANGUAGE plpgsql;
4

2 に答える 2

3

元のコードにいくつかの問題があります。

  1. 変数をリレーションとして使用しようとしているので、代わりに使用RECORDする必要があります。... FROM (SELECT t1.*) s
  2. 1つのレコードを選択し、そのレコードに対してクエリを実行してから実行しても意味count(*)がありません。常に、0または1結果として得られます。

あなたの2番目のバージョンははるかに良く見えます、それのために行ってください。

于 2012-10-26T20:35:31.733 に答える
0

これはうまくいくようです。もっと良いアイデアがあれば教えてください。

CREATE FUNCTION runMortalityModel(a_user_id integer) RETURNS integer AS $$
DECLARE
    t1 RECORD;
    curRecord RECORD;
    numberOfDeaths integer;
BEGIN
    numberOfDeaths := 0;
    FOR curRecord IN 
        SELECT person.id personId, condprobmin, condprobmax, random() experiment 
        FROM person, mortality_cond_prob 
        WHERE (user_id = a_user_id) and 
        (person.age = mortality_cond_prob.age)
    LOOP
        IF (curRecord.condprobmin <= curRecord.experiment) AND     (curRecord.experiment <= curRecord.condprobmax) THEN
            EXECUTE 
                'DELETE '
                || 'FROM person '
                || 'WHERE person.id = ' || curRecord.personId;
            numberOfDeaths := numberOfDeaths + 1;

        END IF;
    END LOOP;

    RETURN numberOfDeaths;
END
$$ LANGUAGE plpgsql;
于 2012-10-26T20:32:49.483 に答える