这是我的问题:
UPDATE invoices SET
version = o.version + 1
,modified = CURRENT_TIMESTAMP
,business_no = $3::numeric
FROM invoices o
LEFT JOIN reps ON reps.rep_id = o.rep_id
LEFT JOIN terms ON terms.terms_id = o.terms_id
LEFT JOIN shipvia ON shipvia.ship_via_id = o.ship_via_id
WHERE o.id = $1::int AND CASE WHEN $2::numeric IS NULL THEN o.business_no IS NULL ELSE o.business_no = $2::numeric END
RETURNING o.id, o.version, o.business_no, ..., terms, rep, ship_via
它应该执行以下操作:
不幸的是,它没有按预期工作。它不是只更新一张发票而是返回新版本,而是:
我理解我的查询错误,我只是无法理解为什么以及如何解决它。
答案 0 :(得分:0)
您的问题是您在FROM列表中指定发票而不将其绑定到UPDATEd的发票表。 manual警告说。所以一个简单的解决方法如下:
UPDATE invoices i
SET version = i.version + 1,
modified = CURRENT_TIMESTAMP,
business_no = $3::numeric
FROM invoices o
LEFT JOIN reps ON reps.rep_id = o.rep_id
LEFT JOIN terms ON terms.terms_id = o.terms_id
LEFT JOIN shipvia ON shipvia.ship_via_id = o.ship_via_id
WHERE o.id = i.id
AND o.id = $1::int
AND ( (o.business_no IS NULL AND $2 IS NULL)
OR (o.business_no = $2::numeric))
RETURNING i.id, i.version, i.business_no, i.modified, reps.name, terms.data, shipvia.who
我有SQLFiddle显示参数的硬编码值。
但是,由于您似乎只是为了RETURNING子句而加入辅助表,您可能想要重新组织整个事情:
WITH o AS (
UPDATE invoices
SET version = version + 1,
modified = CURRENT_TIMESTAMP,
business_no = $3::numeric
WHERE id = $1::int
AND ( (business_no IS NULL AND $2 IS NULL)
OR (business_no = $2::numeric))
RETURNING *
) SELECT o.id, o.version, o.business_no, o.modified, reps.name, terms.data, shipvia.who
FROM o
LEFT JOIN reps ON reps.rep_id = o.rep_id
LEFT JOIN terms ON terms.terms_id = o.terms_id
LEFT JOIN shipvia ON shipvia.ship_via_id = o.ship_via_id;
并更新SQLFiddle以显示第二个版本。我不能说在这种情况下它是否更好,但它是一种可能有益的替代技术。