0

我正在努力让我的“更新后”触发器正常工作。

从我的简单查询中可以看出,production_work 的总和与订单元素的总和相匹配。

# 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.

请注意,我使用的是NEWOLD,而不是 OLD,因为您想使用新值。
但是,如果production_work.order_id可以更改,则必须orders更新OLD NEW

最后一行是防止空更新。

替代方案:查看

如果您不需要冗余列completed来优化性能,我会考虑使用VIEW代替:

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 回答