postgresql 查询从函数中的返回值返回了多行

a1o7rhls  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(151)

我尝试编写一个函数,从SELECT语句插入多个记录,然后将插入的id返回给调用者,但我一直得到错误
错误:查询返回了多个行,CONTEXT:
下面是该函数的简化版本:

CREATE OR REPLACE FUNCTION schema.copy_data(arg_client_id CHAR(30))
RETURNS TABLE (dest_id CHAR(30))
LANGUAGE plpgsql
SECURITY INVOKER
AS $$
DECLARE 
    -- Declare a variable to store the inserted IDs
    inserted_ids CHAR(30)[];
BEGIN
    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 INTO inserted_ids;

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

字符串
老实说,我被难倒了,我在Postgres文档或SO上找不到任何相关的东西。ChatGPT似乎也不能解决这个问题(:

3npbholx

3npbholx1#

你试图把一个 set 硬塞进一个 array 变量,这不是这样工作的。
相反,直接返回集合。当在它,简化为一个普通的SQL函数,不需要PL/pgSQL在这里。

CREATE OR REPLACE FUNCTION my_schema.copy_data(arg_client_id char(30))
  RETURNS TABLE (dest_id char(30))  -- avoid char(n)
  LANGUAGE sql AS  -- SECURITY INVOKER was noise - default anyway
$func$
WITH cte_1 AS (...)
   , cte_2 AS (...)
INSERT INTO my_schema.dest (client_id, fk_id, ...)
SELECT client_id, fk_id, ...
FROM   cte_1
WHERE  NOT EXISTS (
   SELECT FROM cte_2  -- SELECT list can stay empty
   WHERE  cte_1.client_id = cte_2.client_id
   AND    cte_1.fk_id = cte_2.fk_id
   AND ...
  )
RETURNING dest.dest_id;  -- don't prefix schema-name!
$func$;

字符串
您很可能也不需要CTE,而且整个查询可能更简单。
匹配给定的char(30)-对于数据类型来说,这几乎总是一个糟糕的选择:

  • 使用数据类型“text”存储字符串有什么缺点吗?

相关问题