CodeGym /课程 /SQL SELF /如何在PL/pgSQL函数中返回值

如何在PL/pgSQL函数中返回值

SQL SELF
第 50 级 , 课程 1
可用

当你在PostgreSQL里写函数时,第一个要搞明白的事就是怎么返回结果。有时候你只需要返回一个数字,有时候要返回一整张表,有时候甚至要返回好几个数据集。这一节我们把所有常见的方式都过一遍:从最简单的RETURNRETURN QUERYRETURNS TABLESETOF

单个结果:RETURN

如果你的函数只需要返回一个值——比如总数或者行数——那就用普通的RETURN就行。

CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
    total INT;
BEGIN
    SELECT COUNT(*) INTO total FROM students;
    RETURN total;
END;
$$ LANGUAGE plpgsql;

当你在PL/pgSQL里创建函数时,必须指定它返回什么类型。这就是RETURNS关键字的作用,它决定了函数返回结果的“格式”。所以你想返回一个数字、文本还是一张表,都要在RETURNS那一行写清楚。

简单例子:

CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$
BEGIN
    RETURN a + b;
END;
$$ LANGUAGE plpgsql;

这里的RETURNS INT意思就是这个函数会返回一个数字。

返回单个值

我们先从最简单的来——写一个函数,返回一个值。比如,统计students表里学生数量的函数:

CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
    total INT;
BEGIN
    SELECT COUNT(*) INTO total FROM students; -- 把查询结果存到total变量里
    RETURN total; -- 返回结果
END;
$$ LANGUAGE plpgsql;

现在你可以这样调用这个函数:

SELECT count_students(); -- 会返回学生数量

RETURNS TABLE返回多行数据

有时候你不只想返回一个值,而是要返回一堆记录。比如,返回所有学生的id和名字列表。这时候就要用RETURNS TABLE结构。

CREATE FUNCTION get_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY SELECT id, name FROM students; -- 把查询结果作为表返回
END;
$$ LANGUAGE plpgsql;

现在你可以这样用这个函数:

SELECT * FROM get_students(); -- 会返回所有学生的表格

注意RETURNS TABLE关键字。它说明这个函数会返回一个有指定字段(这里是idname)的表。

RETURN QUERY

你应该已经喜欢上上面的例子了。但还有个细节:RETURN QUERY是PL/pgSQL里的魔法棒,可以直接把查询结果返回。用它你可以返回整个查询的结果,也可以只返回一部分。

比如,我们要返回所有状态为active = TRUE的学生:

CREATE FUNCTION get_active_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY
    SELECT id, name
    FROM students
    WHERE active = TRUE; -- 只返回活跃学生
END;
$$ LANGUAGE plpgsql;

现在你可以调用这个函数,拿到所有活跃学生的数据:

SELECT * FROM get_active_students();

不用RETURNS TABLE返回多行

有时候你可能想返回多行数据,但又不想用RETURNS TABLE。这时候可以用SETOF类型。它允许你返回结构一样的多行数据。 比如:

CREATE FUNCTION get_student_names() RETURNS SETOF TEXT AS $$
BEGIN
    RETURN QUERY
    SELECT name
    FROM students;
END;
$$ LANGUAGE plpgsql;

这个函数只会返回学生名字的列表:

SELECT * FROM get_student_names();

根据输入参数返回不同的值

函数不一定只返回静态结果。它们可以用参数动态改变返回内容。

比如,按学生id返回数据的例子:

CREATE FUNCTION get_student_by_id(student_id INT) RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY
    SELECT id, name
    FROM students
    WHERE id = student_id; -- 用student_id参数
END;
$$ LANGUAGE plpgsql;

现在你可以查某个学生的信息:

SELECT * FROM get_student_by_id(3); -- 会返回ID=3的学生数据

返回复杂数据(多个数据集)

有时候数据太复杂,需要分几组返回。这时候可以用游标。比如,你想从一个函数里返回两个数据集——活跃学生和不活跃学生的列表。

CREATE FUNCTION get_students_status() RETURNS SETOF RECORD AS $$
BEGIN
    RETURN QUERY
    SELECT id, name, 'active' AS status
    FROM students
    WHERE active = TRUE;

    RETURN QUERY
    SELECT id, name, 'inactive' AS status
    FROM students
    WHERE active = FALSE;
END;
$$ LANGUAGE plpgsql;

现在你可以拿到这两组数据:

SELECT * FROM get_students_status();

RETURNS时常见的坑

没写返回类型: 如果你没写函数返回什么类型,PostgreSQL会报错。比如:

CREATE FUNCTION no_return_type() AS $$ -- 错误,没写RETURNS
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

数据类型不匹配: 要保证你返回的值和声明的类型一致。比如你写了INT,就别返回字符串。

忘了用RETURN QUERY 如果你忘了在复杂查询里用RETURN QUERY,函数啥都不会返回。

多值返回写错: 如果你想返回多行数据,但没用SETOFTABLE,PostgreSQL也会报错。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION