Hasura调用plpgsql函数报query has no destination for result data错误怎么办
问题排查:PL/pgSQL函数返回结果报错
你遇到的query has no destination for result data报错是PL/pgSQL的语法规则导致的:在PL/pgSQL代码块中直接执行SELECT语句时,数据库默认要求为查询结果指定存储变量,如果要将查询结果作为函数返回值输出,必须显式使用RETURN QUERY关键字声明。
修正后的无参测试函数代码如下:
CREATE OR REPLACE FUNCTION dms.fngetdocs() RETURNS SETOF dms.t_documents LANGUAGE plpgsql STABLE AS $function$ BEGIN -- 新增RETURN QUERY声明将查询结果作为函数返回值 RETURN QUERY SELECT * FROM dms.t_documents; END; $function$
支持多可选参数的动态查询函数实现
可选参数通过设置DEFAULT NULL默认值实现,根据业务逻辑复杂度可以选择两种实现方案:
方案1:静态WHERE条件实现(无SQL注入风险,推荐)
直接在WHERE语句中通过参数非空判断实现动态过滤,不需要写IF分支,代码更简洁,适合常规过滤场景:
CREATE OR REPLACE FUNCTION dms.fngetdocs( p_doc_id INT DEFAULT NULL, p_title TEXT DEFAULT NULL, p_create_start TIMESTAMPTZ DEFAULT NULL ) RETURNS SETOF dms.t_documents LANGUAGE plpgsql STABLE AS $function$ BEGIN RETURN QUERY SELECT * FROM dms.t_documents WHERE -- 对应参数为NULL时该条件自动失效,不参与过滤 (p_doc_id IS NULL OR id = p_doc_id) AND (p_title IS NULL OR title ILIKE CONCAT('%', p_title, '%')) AND (p_create_start IS NULL OR create_time >= p_create_start); END; $function$
方案2:IF分支判断实现(适合复杂分支逻辑场景)
如果业务需要根据参数存在情况走完全不同的查询逻辑,可以用IF分支分开定义查询语句:
CREATE OR REPLACE FUNCTION dms.fngetdocs( p_doc_type INT DEFAULT NULL, p_is_deleted BOOLEAN DEFAULT FALSE ) RETURNS SETOF dms.t_documents LANGUAGE plpgsql STABLE AS $function$ BEGIN -- 传入文档类型参数时走指定逻辑 IF p_doc_type IS NOT NULL THEN RETURN QUERY SELECT * FROM dms.t_documents WHERE doc_type = p_doc_type AND is_deleted = p_is_deleted; -- 未传文档类型时走全量逻辑 ELSE RETURN QUERY SELECT * FROM dms.t_documents WHERE is_deleted = p_is_deleted; END IF; END; $function$
注意事项
- 函数创建完成后在Hasura中重新跟踪即可,所有设置了默认值的参数都会在GraphQL schema中自动标记为可选参数
- 如果需要新增更多查询参数,只需要在参数定义区按格式新增带默认值的参数,对应调整WHERE条件或者IF分支即可
内容的提问来源于stack exchange,提问作者sarak
相关产品推荐
相关产品推荐

