PostgreSQL存储过程查询员工报错:无结果数据目标如何解决?
解决PostgreSQL存储过程中SELECT结果无目的地的错误
错误原因
PostgreSQL的PL/pgSQL存储过程(PROCEDURE)与SQL Server的存储过程行为存在差异:SQL Server中存储过程内的SELECT语句会自动将结果返回给调用者,但PostgreSQL要求必须显式指定查询结果的去向——要么将结果赋值给变量,要么通过输出机制返回,否则就会抛出query has no destination for result data错误。
解决方案
针对你的查询场景,更推荐使用函数(FUNCTION)而非存储过程,因为PostgreSQL的函数设计更适合返回查询结果集;如果一定要用存储过程,也可以通过显式输出结果的方式解决。
方案1:改用函数(推荐)
函数可以直接通过RETURN QUERY返回结果集,写法简洁,调用也更方便:
方式A:通用结果集返回(无需提前定义列)
DROP FUNCTION IF EXISTS GetbyID(p_ID TEXT); CREATE OR REPLACE FUNCTION GetbyID(p_ID TEXT) RETURNS SETOF record LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT * FROM "Employee" AS M LEFT OUTER JOIN "Position" AS F1 ON M."PositionID" = F1."PositionID_P" LEFT OUTER JOIN "Department" AS F2 ON F1."DepartmentID_P" = F2."DepartmentID" WHERE M."ID" = p_ID; END; $$;
调用时需要指定结果列的结构(需与查询返回的列顺序、类型一致):
SELECT * FROM GetbyID('E12345') AS ( emp_id TEXT, emp_name TEXT, emp_position_id INT, pos_id INT, pos_name TEXT, pos_dept_id INT, dept_id INT, dept_name TEXT -- 根据你的实际表结构补充剩余列 );
方式B:明确返回列结构(调用更便捷)
如果提前知道查询返回的列,可以直接在函数中定义返回表结构,调用时无需额外指定列:
DROP FUNCTION IF EXISTS GetbyID(p_ID TEXT); CREATE OR REPLACE FUNCTION GetbyID(p_ID TEXT) RETURNS TABLE( emp_id TEXT, emp_name TEXT, emp_position_id INT, pos_id INT, pos_name TEXT, pos_dept_id INT, dept_id INT, dept_name TEXT ) LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT M."ID", M."Name", M."PositionID", F1."PositionID_P", F1."Name", F1."DepartmentID_P", F2."DepartmentID", F2."Name" FROM "Employee" AS M LEFT OUTER JOIN "Position" AS F1 ON M."PositionID" = F1."PositionID_P" LEFT OUTER JOIN "Department" AS F2 ON F1."DepartmentID_P" = F2."DepartmentID" WHERE M."ID" = p_ID; END; $$;
调用方式:
SELECT * FROM GetbyID('E12345');
方案2:修改存储过程以返回结果
如果必须使用存储过程,可以通过OUT参数结合循环输出结果:
DROP PROCEDURE IF EXISTS GetbyID(p_ID TEXT, OUT result_record record); CREATE OR REPLACE PROCEDURE GetbyID(p_ID TEXT, OUT result_record record) LANGUAGE plpgsql AS $$ BEGIN FOR result_record IN SELECT * FROM "Employee" AS M LEFT OUTER JOIN "Position" AS F1 ON M."PositionID" = F1."PositionID_P" LEFT OUTER JOIN "Department" AS F2 ON F1."DepartmentID_P" = F2."DepartmentID" WHERE M."ID" = p_ID LOOP RETURN NEXT; END LOOP; END; $$;
调用方式:
CALL GetbyID('E12345', NULL);
总结
对于查询并返回结果的场景,PostgreSQL的函数是更合适的选择,语法更简洁且符合PostgreSQL的设计习惯;存储过程通常用于执行数据修改、事务控制等不需要返回结果集的操作。
内容的提问来源于stack exchange,提问作者Alan
相关产品推荐
相关产品推荐

