1
CREATE TABLE lab7.standings
(
    team_name    VARCHAR(100) NOT NULL PRIMARY KEY,
    wins         INTEGER,
    losses       INTEGER,
    winPct       NUMERIC,
    CHECK(wins > 0),
    CHECK(losses >0)
);

CREATE OR REPLACE FUNCTION
calc_winning_percentage()
RETURNS trigger AS $$
BEGIN
    New.winPct := New.wins /(New.wins + New.losses);
    RETURN NEW;
END;
$$LANGUAGE plpgsql;

CREATE TRIGGER
update_winning_percentage
AFTER INSERT OR UPDATE ON standings
FOR EACH ROW EXECUTE PROCEDURE calc_winning_percentage();

これは私の順位表の勝率を正確に更新していますが、計算された新しい勝率を送信していないようです。

4

2 に答える 2

2

@Grijeshによって指摘されたBEFOREようにトリガーを変更することに加えて:

私はあなたのテーブル定義に3つのことに気づきました:

1.integer対。numeric

winslossesタイプintegerですが、winPctですnumeric

次のことを試してください。

SELECT 1 / 4, 2 / 4

0あなたに両方の時間を与えます。結果はタイプintegerであり、小数桁はゼロに向かって切り捨てられます。これは、割り当てで結果が強制される前に、トリガー関数で発生します。したがって、小数桁にのみ影響する変更は結果に失われます。これを修正するには:integernumericwinslosses

..列定義numericベーステーブルの関連するすべての列に対して変更する。
..またはトリガー機能の変更:

NEW.winPct := NEW.wins::numeric / (NEW.wins + NEW.losses);

計算の数値の1つをnumeric::numeric)にキャストすると、結果は強制的にnumeric小数桁になり、保持されます。

は明らかにとの正しいタイプであるため、2番目のバリアントを強くお勧めします。パーセンテージが非常に正確である必要がない場合は、パーセンテージに単純な浮動小数点型またはを使用することも検討します。次に、トリガーは以下を使用できます。integerwinslossesrealdouble precision

NEW.winPct := NEW.wins::float8 / (NEW.wins + NEW.losses);

2.引用符で囲まれていない列名winPct

小文字にキャストされ、事実上ちょうどwinpctPostgreSQLの識別子について必ずお読みください。

3.スキーマ

テーブルは明らかに非標準スキーマに存在します:lab7.standings。それがに含まれていない限りsearch_path、トリガーの作成にはスキーマ修飾名を使用する必要があります。

...
BEFORE INSERT OR UPDATE ON lab7.standings
...

PS

この種の質問でテーブル定義を投稿することの重要性を示します。

于 2013-03-16T21:03:55.453 に答える
2

これを試して:

CREATE TRIGGER update_winning_percentage
BEFORE INSERT OR UPDATE ON standings
FOR EACH ROW EXECUTE PROCEDURE calc_winning_percentage();
于 2013-03-16T19:09:46.620 に答える