使用表名限定时,Postgres列引用不明确

时间:2018-06-30 03:07:23

标签: postgresql

这是一个中等复杂的CTE,它根据JSON参数的内容更新许多表。执行此功能时, Postgres引发column reference "explode" is ambiguous错误。错误所指的行实际上是具有限定列引用的表名。

我很确定我是对引起问题的那一行是正确的,就像我删除下面标记的行一样,该错误消失了。

一段时间以来,我一直试图弄清楚这一点,我不知道。

CREATE OR REPLACE FUNCTION prd.update_composition (json, OUT result json) AS
$$
BEGIN
  -- Update and return the new composition
  WITH composition AS (
    UPDATE prd.composition SET (
      explode
    ) = (
      payload_composition.explode
    )
    FROM json_to_record($1) AS payload_composition (
      id      integer,
      explode boolean
    )
    WHERE id IS NOT NULL
    RETURNING *
  ), payload_component AS (
    SELECT
      composition.composition_id,
      component."productId" AS product_id,
      component.quantity,
      component.removed
    FROM json_to_recordset($1->'components') AS component (
      "productId" integer,
      quantity    numeric(10,3),
      removed     boolean
    )
    CROSS JOIN composition
  ), updated_component AS (
    UPDATE prd.component existing SET (
      product_id,
      quantity
    ) = (
      component.product_id,
      component.quantity
    )
    FROM (
      SELECT
        composition_id,
        product_id,
        quantity
      FROM payload_component
      WHERE removed IS NOT TRUE
    ) component
    WHERE existing.composition_id = component.composition_id
    RETURNING *
  ), deleted AS (
    DELETE FROM prd.component existing
    USING (
      SELECT
        composition_id,
        product_id
      FROM payload_component
      WHERE removed IS TRUE
    ) payload_deleted
    WHERE existing.composition_id = payload_deleted.composition_id
      AND existing.product_id = payload_deleted.product_id
  )
  SELECT json_strip_nulls(to_json(r)) INTO result
  FROM (
    SELECT
      composition.composition_id,
      composition.explode -- HERE IS THE OFFENDING LINE --
    FROM composition
  ) r;
END
$$
LANGUAGE 'plpgsql' SECURITY DEFINER;

为什么会有这样的ambiguous column reference error代码?

1 个答案:

答案 0 :(得分:0)

问题出在22:49:29.438 [main] 500 example.SomeClass - This is some debug! 22:49:29.440 [main] 400 example.SomeClass - Here's some info! 22:49:29.440 [main] 200 example.SomeClass - Some erorr happened! CTE中的RETURNING子句中。

通过将composition*一起使用,它将返回RETURNING中所有表的所有列。

returning子句应指定要返回的列和表, 尤其是在from_list中有多个表的情况下。

在这种情况下,应在from_list中使用别名来引用必需的 列:

INSERT