You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL函数中INSERT...RETURNING返回多行报错求助

问题根源

报错ERROR: query returned more than one row的原因是:你试图用RETURNING ... INTO inserted_ids将INSERT语句返回的多行ID直接赋值给数组变量,但PostgreSQL中这种写法仅支持单行返回值。当INSERT插入多条记录时,RETURNING返回多行,这种赋值方式会触发错误。

解决方案

方案一:直接返回INSERT的RETURNING结果(推荐)

无需中间数组变量,直接将INSERT操作的RETURNING结果作为函数的返回数据集,代码更简洁高效:

CREATE OR REPLACE FUNCTION schema.copy_data(arg_client_id CHAR(30))
RETURNS TABLE (dest_id CHAR(30))
LANGUAGE plpgsql
SECURITY INVOKER
AS $$
BEGIN
    RETURN QUERY
    WITH
    cte_1 AS (...),
    cte_2 AS (...)
    INSERT INTO schema.dest
    (client_id, fk_id, ...)
    SELECT client_id, fk_id, ...
    FROM cte_1
    WHERE NOT EXISTS(
        SELECT 1 FROM cte_2
        WHERE cte_1.client_id = cte_2.client_id
          AND cte_1.fk_id = cte_2.fk_id
          AND ...
    )
    RETURNING schema.dest.dest_id;
END
$$;

方案二:通过数组变量存储ID(如需额外处理)

如果必须将插入的ID存储到数组变量中做后续处理,需要用ARRAY_AGG将RETURNING返回的多行ID聚合为数组后再赋值:

CREATE OR REPLACE FUNCTION schema.copy_data(arg_client_id CHAR(30))
RETURNS TABLE (dest_id CHAR(30))
LANGUAGE plpgsql
SECURITY INVOKER
AS $$
DECLARE 
    inserted_ids CHAR(30)[];
BEGIN
    WITH
    cte_1 AS (...),
    cte_2 AS (...)
    SELECT ARRAY_AGG(dest_id) INTO inserted_ids
    FROM (
        INSERT INTO schema.dest
        (client_id, fk_id, ...)
        SELECT client_id, fk_id, ...
        FROM cte_1
        WHERE NOT EXISTS(
            SELECT 1 FROM cte_2
            WHERE cte_1.client_id = cte_2.client_id
              AND cte_1.fk_id = cte_2.fk_id
              AND ...
        )
        RETURNING schema.dest.dest_id
    ) AS inserted_records;

    RETURN QUERY SELECT dest_id FROM UNNEST(inserted_ids) AS dest_id;
END
$$;

内容的提问来源于stack exchange,提问作者Philippe Hebert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 13:23:15