0

「更新後」トリガーを適切に機能させるのに苦労しています。

私の単純なクエリからわかるように、production_work の合計は order 要素の合計と一致します。

# select ident,ud,dp,swrv,sh,jmsw,sw,prrv,mhsw,bmsw,mp,pr,st,completed from orders;
 ident | ud | dp | swrv | sh | jmsw | sw | prrv | mhsw | bmsw | mp | pr | st | completed 
-------+----+----+------+----+------+----+------+------+------+----+----+----+-----------
     2 |  1 |  1 |    0 |  0 |    0 |  0 |    0 |    0 |    0 |  0 |  0 |  0 | f
(1 row)

# select * from production_work;
 ident | order_id | producer_id |    day     | ud | dp | swrv | sh | jmsw | sw | prrv | mhsw | bmsw | mp | pr | st 
-------+----------+-------------+------------+----+----+------+----+------+----+------+------+------+----+----+----
     5 |        2 |           1 | 2013-08-09 |  1 |  0 |    0 |  0 |    0 |  0 |    0 |    0 |    0 |  0 |  0 |  0
     6 |        2 |           2 | 2013-08-09 |  0 |  1 |    0 |  0 |    0 |  0 |    0 |    0 |    0 |  0 |  0 |  0
(2 rows)

このトリガーを使用して、作業要素の合計が注文要素と一致する場合、「完了」を true に設定しようとしています。

CREATE OR REPLACE FUNCTION update_order_completion_status() RETURNS trigger AS
$BODY$
BEGIN
    WITH w AS (
            SELECT SUM(ud) AS ud, SUM(dp) AS dp, SUM(swrv) AS swrv, SUM(sh) AS sh, SUM(jmsw) AS jmsw, SUM(sw) AS sw, SUM(prrv) AS prrv,
                    SUM(mhsw) AS mhsw, SUM(bmsw) AS bmsw, SUM(mp) AS mp, SUM(pr) AS pr, SUM(st) AS st
            FROM production_work
            WHERE order_id = OLD.order_id
    ), o AS (
            SELECT ud, dp, swrv, sh, jmsw, sw, prrv, mhsw, bmsw, mp, pr, st
            FROM orders
            WHERE ident = OLD.order_id
    )
    UPDATE orders
    SET completed = (w.ud = o.ud AND w.dp = o.dp AND w.swrv = o.swrv AND w.sh = o.sh AND w.jmsw = o.jmsw AND w.sw = o.sw AND
                    w.prrv = o.prrv AND w.mhsw = o.mhsw AND w.bmsw = o.bmsw AND w.mp = o.mp AND w.pr = o.pr AND w.st = o.st)
    WHERE ident = OLD.order_id;
END;
$BODY$ LANGUAGE plpgsql ;

CREATE TRIGGER update_order_completion_status_trigger
AFTER UPDATE OF ud, dp, swrv, sh, jmsw, sw, prrv, mhsw, bmsw, mp, pr, st
ON production_work
FOR EACH ROW EXECUTE PROCEDURE update_order_completion_status();

production_work テーブルを更新してもエラー メッセージは表示されませんが、完了した列が true に設定されていません。

4

1 に答える 1

0

トリガー関数の SQL クエリは不必要に複雑であり、正しくもありません (FROMの句がありませUPDATEん)。簡略化された正しいバージョンは次のようになります。

UPDATE orders o
SET    completed = (w.ud = o.ud AND w.dp = o.dp AND ...)
FROM (
    SELECT SUM(ud) AS ud, SUM(dp) AS dp, ...
    FROM   production_work
    WHERE  order_id = NEW.order_id
    ) w
WHERE  o.ident = NEW.order_id
AND    o.completed <> (w.ud = o.ud AND w.dp = o.dp AND ...);

仮定しcompleted NOT NULLます。

NEW新しい値を使用したいので、OLD ではなく を使用していることに注意してください。
ただし、production_work.order_id変更できる場合は、 と を更新するorders必要がOLD あり NEWます。

最後の行は、空の更新を防ぐためのものです。

代替: ビュー

パフォーマンスを最適化するために冗長な列が必要ない場合は、代わりにVIEWcompletedを検討します。

CREATE VIEW order_plus AS
SELECT o.*, (SUM(w.ud) = o.ud AND SUM(w.dp) = o.dp AND ...) AS completed
FROM   orders o
JOIN   production_work w ON o.ident = w.ident
GROUP  BY o.ident;

仮定しident PRIMARY KEYます。

于 2013-08-10T15:06:26.870 に答える