CodeGym /课程 /SQL SELF /创建简单函数:CREATE FUNCTION

创建简单函数:CREATE FUNCTION

SQL SELF
第 50 级 , 课程 0
可用

在PostgreSQL里,函数是个超强工具,可以帮你自动化任务、写业务逻辑,让服务器变得更聪明。你可以把函数想象成数据库里的小程序。它们很适合:

  • 代码复用。如果你老是写一样的查询,把它们包进函数里,想用就直接调。
  • 自动化任务。比如你要根据员工工时算工资,用函数就很方便。
  • 封装逻辑。把复杂的计算都放到服务器端,客户端不用再纠结SQL怎么写。

CREATE FUNCTION的基本语法

函数的基本结构长这样:

CREATE FUNCTION function_name(parameters) RETURNS return_type AS $$
BEGIN
    -- 函数体(逻辑)
    RETURN 结果;
END;
$$ LANGUAGE plpgsql;

来拆解一下主要部分:

CREATE FUNCTION function_name(parameters)

这行是给函数起名字function_name,还可以加参数(如果需要的话)。

参数可以写名字和类型:my_param INTEGERanother_param TEXT

RETURNS return_type

这里写函数要返回啥:一个值(INTEGERTEXT啥的)或者一堆数据(TABLERECORD)。

BEGIN ... END

这俩关键词中间就是“函数体”,所有操作都在这儿写。

RETURN 结果

返回函数执行的结果。注意:返回值类型要和RETURNS里写的一样。

LANGUAGE plpgsql

这里指定用PL/pgSQL语言。PostgreSQL还支持别的语言,但我们现在就用这个。

简单例子:两个数相加

来写个函数,返回两个整数的和。

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

现在来调用一下:

SELECT add_numbers(5, 7); -- 结果:12

发生了啥?

  • 函数接收两个参数ab,类型都是INT
  • 函数体里直接把它们加起来(a + b),然后返回。
  • 就像个计算器一样简单!

用变量的例子

假设我们有个大学的数据库,想知道有多少学生注册了。

写个函数:

CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
    total INT; -- 声明个变量存结果
BEGIN
    SELECT COUNT(*) INTO total FROM students; -- 统计表里有多少行
    RETURN total; -- 返回结果
END;
$$ LANGUAGE plpgsql;

调用函数:

SELECT count_students(); -- 假设结果:120

这里我们看到:

  • 用变量total来存SQL查询的结果。
  • SELECT ... INTO语句把查询结果塞进变量里。

这种写法很适合你要先处理下数据再返回的场景。

返回多个值:RETURNS TABLE

上面例子只返回了一个值。如果你想让函数返回一堆数据,比如学生列表,就要用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();

可能的结果:

id name
1 Alice
2 Bob
3 Charlie

RETURN QUERY的好处:直接在函数里查数据

RETURN QUERY让你可以直接把SQL查询的结果返回出去,省了中间变量,函数更简洁。

写个函数,只返回活跃的学生:

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;

在调用get_active_students()前,得先建个students表并插点测试数据。可以这样:

-- 创建学生表
CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    active BOOLEAN DEFAULT TRUE
);

-- 插入几条记录
INSERT INTO students (name, active) VALUES
('Alice', FALSE),
('Bob', TRUE),
('Charlie', TRUE),
('Dana', FALSE);

表格:

id name active
1 Alice false
2 Bob true
3 Charlie true
4 Dana false

现在调用:

SELECT * FROM get_active_students();

结果:

id name
2 Bob
3 Charlie

执行前校验数据的正确性

函数里可以用IF判断,保证数据没问题。比如,只有学生所有考试都过了,才能升到下一级。

例子:

CREATE FUNCTION promote_student(student_id INT) RETURNS TEXT AS $$
DECLARE
    passed_exams INT;
BEGIN
    -- 统计学生通过的考试数量
    SELECT COUNT(*) INTO passed_exams
    FROM exams
    WHERE student_id = promote_student.student_id AND status = '通过';

    -- 判断条件
    IF passed_exams < 5 THEN
        RETURN '学生通过的考试不够';
    END IF;

    -- 更新学生年级
    UPDATE students
    SET course = course + 1
    WHERE id = promote_student.student_id;

    RETURN '学生已升级!';
END;
$$ LANGUAGE plpgsql;

写函数时常见的坑

没写返回值类型。PostgreSQL要求你必须写清楚函数返回啥。比如:

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

修正:

CREATE FUNCTION succeed() RETURNS INT AS $$
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

返回值类型不对。你写了RETURNS INT,就得返回数字。要是返回字符串就不行。

函数里的SQL写错了。用函数前一定要先单独测试下SQL,最好在psqlpgAdmin里手动跑一遍。

2
任务
SQL SELF, 第 50 级, 课程 0
已锁定
计算员工工资总额
计算员工工资总额
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION