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

PostgreSQL返回SETOF类型函数报错:RETURN cannot have a parameter求解决

问题:PostgreSQL函数报错RETURN cannot have a parameter in function returning set的原因及修复

我编写了如下PostgreSQL PL/pgSQL代码,但运行时抛出错误:
RETURN cannot have a parameter in function returning set

代码如下:

DROP FUNCTION IF EXISTS public.get_services_connected_for_workspace;
DROP FUNCTION IF EXISTS public.get_services_connected_data;

CREATE OR REPLACE FUNCTION public.get_services_connected_for_workspace(_workspace_id BIGINT)
 RETURNS SETOF services_connected_response
 LANGUAGE plpgsql
AS $function$
DECLARE
  results services_connected_response[];
  services_connected_row services_connected_response;
BEGIN
  SELECT ARRAY[
    ('github', COALESCE(service_github.auto_invite, false), services_connected.service_github IS NOT NULL, false, COALESCE(service_github.last_synced, NULL), COALESCE(service_github.sync_status, NULL)),
    ('zoom', COALESCE(service_zoom.auto_invite, false), services_connected.service_zoom IS NOT NULL, false, COALESCE(service_zoom.last_synced, NULL), COALESCE(service_zoom.sync_status, NULL)),
    ('jira', COALESCE(service_jira.auto_invite, false), services_connected.service_jira IS NOT NULL, false, COALESCE(service_jira.last_synced, NULL), COALESCE(service_jira.sync_status, NULL)),
    ('docusign', COALESCE(service_docusign.auto_invite, false), services_connected.service_docusign IS NOT NULL, false, COALESCE(service_docusign.last_synced, NULL), COALESCE(service_docusign.sync_status, NULL)),
    ('asana', COALESCE(service_asana.auto_invite, false), services_connected.service_asana IS NOT NULL, false, COALESCE(service_asana.last_synced, NULL), COALESCE(service_asana.sync_status, NULL)),
    ('google', COALESCE(service_google.auto_invite, false), services_connected.service_google IS NOT NULL, true, COALESCE(service_google.last_synced, NULL), COALESCE(service_google.sync_status, NULL))
  ]
  INTO results
  FROM services_connected
  LEFT JOIN service_github ON services_connected.service_github = service_github.id
  LEFT JOIN service_jira ON services_connected.service_jira = service_jira.id
  LEFT JOIN service_zoom ON services_connected.service_zoom = service_zoom.id
  LEFT JOIN service_asana ON services_connected.service_asana = service_asana.id
  LEFT JOIN service_docusign ON services_connected.service_docusign = service_docusign.id
  LEFT JOIN service_google ON services_connected.service_google = service_google.id
  WHERE services_connected.workspace_id = _workspace_id;
  RETURN results;
END;
$function$;

CREATE OR REPLACE FUNCTION public.get_services_connected_data()
 RETURNS SETOF services_connected_response
 LANGUAGE plpgsql
AS $function$
DECLARE
  _workspace_id BIGINT := ((current_setting('request.jwt.claims'::text, TRUE))::JSON ->> 'workspace_id')::BIGINT;
BEGIN
   RETURN QUERY
    SELECT *
    FROM public.get_services_connected_for_workspace(_workspace_id);
END;
$function$;

错误原因

get_services_connected_for_workspace函数声明返回SETOF services_connected_response(即返回一组行数据),但你在函数末尾用了RETURN results;——这里的results是数组类型,而RETURN 直接带参数的语法只适用于返回单个值的函数,对于返回集合的函数,这种写法不符合PL/pgSQL的语法规则,因此触发了该错误。

修复方案

方案1:遍历数组返回每一行

保留数组变量,通过循环遍历数组中的每个元素,用RETURN NEXT逐个返回:

DROP FUNCTION IF EXISTS public.get_services_connected_for_workspace;
DROP FUNCTION IF EXISTS public.get_services_connected_data;

CREATE OR REPLACE FUNCTION public.get_services_connected_for_workspace(_workspace_id BIGINT)
 RETURNS SETOF services_connected_response
 LANGUAGE plpgsql
AS $function$
DECLARE
  results services_connected_response[];
  services_connected_row services_connected_response;
BEGIN
  SELECT ARRAY[
    ('github', COALESCE(service_github.auto_invite, false), services_connected.service_github IS NOT NULL, false, COALESCE(service_github.last_synced, NULL), COALESCE(service_github.sync_status, NULL)),
    ('zoom', COALESCE(service_zoom.auto_invite, false), services_connected.service_zoom IS NOT NULL, false, COALESCE(service_zoom.last_synced, NULL), COALESCE(service_zoom.sync_status, NULL)),
    ('jira', COALESCE(service_jira.auto_invite, false), services_connected.service_jira IS NOT NULL, false, COALESCE(service_jira.last_synced, NULL), COALESCE(service_jira.sync_status, NULL)),
    ('docusign', COALESCE(service_docusign.auto_invite, false), services_connected.service_docusign IS NOT NULL, false, COALESCE(service_docusign.last_synced, NULL), COALESCE(service_docusign.sync_status, NULL)),
    ('asana', COALESCE(service_asana.auto_invite, false), services_connected.service_asana IS NOT NULL, false, COALESCE(service_asana.last_synced, NULL), COALESCE(service_asana.sync_status, NULL)),
    ('google', COALESCE(service_google.auto_invite, false), services_connected.service_google IS NOT NULL, true, COALESCE(service_google.last_synced, NULL), COALESCE(service_google.sync_status, NULL))
  ]
  INTO results
  FROM services_connected
  LEFT JOIN service_github ON services_connected.service_github = service_github.id
  LEFT JOIN service_jira ON services_connected.service_jira = service_jira.id
  LEFT JOIN service_zoom ON services_connected.service_zoom = service_zoom.id
  LEFT JOIN service_asana ON services_connected.service_asana = service_asana.id
  LEFT JOIN service_docusign ON services_connected.service_docusign = service_docusign.id
  LEFT JOIN service_google ON services_connected.service_google = service_google.id
  WHERE services_connected.workspace_id = _workspace_id;

  -- 遍历数组,逐个返回元素
  FOREACH services_connected_row IN ARRAY results LOOP
    RETURN NEXT services_connected_row;
  END LOOP;
  
  RETURN; -- 无参数的RETURN用于结束函数
END;
$function$;

CREATE OR REPLACE FUNCTION public.get_services_connected_data()
 RETURNS SETOF services_connected_response
 LANGUAGE plpgsql
AS $function$
DECLARE
  _workspace_id BIGINT := ((current_setting('request.jwt.claims'::text, TRUE))::JSON ->> 'workspace_id')::BIGINT;
BEGIN
   RETURN QUERY
    SELECT *
    FROM public.get_services_connected_for_workspace(_workspace_id);
END;
$function$;

方案2:直接用RETURN QUERY返回行(更高效简洁)

不需要先把结果转成数组,直接用RETURN QUERY返回构造的行数据,这是PL/pgSQL返回集合的推荐写法,避免数组转换的额外开销:

DROP FUNCTION IF EXISTS public.get_services_connected_for_workspace;
DROP FUNCTION IF EXISTS public.get_services_connected_data;

CREATE OR REPLACE FUNCTION public.get_services_connected_for_workspace(_workspace_id BIGINT)
 RETURNS SETOF services_connected_response
 LANGUAGE plpgsql
AS $function$
BEGIN
  RETURN QUERY
  SELECT 
    ('github', COALESCE(service_github.auto_invite, false), services_connected.service_github IS NOT NULL, false, COALESCE(service_github.last_synced, NULL), COALESCE(service_github.sync_status, NULL))::services_connected_response,
    ('zoom', COALESCE(service_zoom.auto_invite, false), services_connected.service_zoom IS NOT NULL, false, COALESCE(service_zoom.last_synced, NULL), COALESCE(service_zoom.sync_status, NULL))::services_connected_response,
    ('jira', COALESCE(service_jira.auto_invite, false), services_connected.service_jira IS NOT NULL, false, COALESCE(service_jira.last_synced, NULL), COALESCE(service_jira.sync_status, NULL))::services_connected_response,
    ('docusign', COALESCE(service_docusign.auto_invite, false), services_connected.service_docusign IS NOT NULL, false, COALESCE(service_docusign.last_synced, NULL), COALESCE(service_docusign.sync_status, NULL))::services_connected_response,
    ('asana', COALESCE(service_asana.auto_invite, false), services_connected.service_asana IS NOT NULL, false, COALESCE(service_asana.last_synced, NULL), COALESCE(service_asana.sync_status, NULL))::services_connected_response,
    ('google', COALESCE(service_google.auto_invite, false), services_connected.service_google IS NOT NULL, true, COALESCE(service_google.last_synced, NULL), COALESCE(service_google.sync_status, NULL))::services_connected_response
  FROM services_connected
  LEFT JOIN service_github ON services_connected.service_github = service_github.id
  LEFT JOIN service_jira ON services_connected.service_jira = service_jira.id
  LEFT JOIN service_zoom ON services_connected.service_zoom = service_zoom.id
  LEFT JOIN service_asana ON services_connected.service_asana = service_asana.id
  LEFT JOIN service_docusign ON services_connected.service_docusign = service_docusign.id
  LEFT JOIN service_google ON services_connected.service_google = service_google.id
  WHERE services_connected.workspace_id = _workspace_id;
END;
$function$;

CREATE OR REPLACE FUNCTION public.get_services_connected_data()
 RETURNS SETOF services_connected_response
 LANGUAGE plpgsql
AS $function$
DECLARE
  _workspace_id BIGINT := ((current_setting('request.jwt.claims'::text, TRUE))::JSON ->> 'workspace_id')::BIGINT;
BEGIN
   RETURN QUERY
    SELECT *
    FROM public.get_services_connected_for_workspace(_workspace_id);
END;
$function$;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:45:54