函数与存储过程
掌握自定义函数的编写
了解 PL/pgSQL 基础语法
区分函数与存储过程的区别
核心讲解
(1)PL/pgSQL
PostgreSQL 的过程语言,支持变量、判断、循环、异常,用来编写函数和存储过程。
(2)自定义函数
可以返回标量、表,支持 SQL 调用。
创建:
CREATE FUNCTION 函数名(参数) RETURNS 返回类型 AS $$ ... $$ LANGUAGE plpgsql;调用:
SELECT 函数名(参数);特点:可以在 SQL 语句里调用,返回结果
(3)存储过程
和函数类似,但没有返回值,支持事务控制。
创建:
CREATE PROCEDURE 过程名(参数) AS $$ ... $$ LANGUAGE plpgsql;调用:
CALL 过程名(参数);适合:复杂业务逻辑、事务处理
(4)基础语法
变量声明:
变量名 类型 := 默认值;赋值:
变量 := 值;判断:
IF ... THEN ... ELSIF ... ELSE ... END IF;循环:
FOR i IN 1..10 LOOP ... END LOOP;返回:
RETURN 值;
代码示例
-- ===== 1. 简单函数:求两数之和 =====
CREATE OR REPLACE FUNCTION add_num(a int, b int)
RETURNS int AS $$
BEGIN
RETURN a + b;
END;
$$ LANGUAGE plpgsql;
-- 调用
SELECT add_num(10, 20);
-- ===== 2. 返回表的函数 =====
CREATE OR REPLACE FUNCTION get_students_by_class(cid int)
RETURNS SETOF student AS $$
BEGIN
RETURN QUERY SELECT * FROM student WHERE class_id = cid;
END;
$$ LANGUAGE plpgsql;
-- 调用
SELECT * FROM get_students_by_class(1);
-- ===== 3. 存储过程:批量插入 =====
CREATE OR REPLACE PROCEDURE batch_insert_student(count int)
AS $$
DECLARE
i int := 1;
BEGIN
FOR i IN 1..count LOOP
INSERT INTO student(name, class_id)
VALUES ('学生_' || i, floor(random()*2 + 1));
END LOOP;
END;
$$ LANGUAGE plpgsql;
-- 调用存储过程
CALL batch_insert_student(10);
-- 验证
SELECT COUNT(*) FROM student;
常见误区
函数和存储过程分不清:函数有返回值,可以 SELECT 调用;存储过程没有,CALL 调用,支持独立事务
用函数做增删改:函数尽量只读,修改数据用存储过程或者 SQL
语法和 MySQL 一样:PL/pgSQL 和 MySQL 的存储过程语法不一样,注意区分
课后练习
写一个函数,传入学生 ID,返回姓名
写一个函数,计算 n 的阶乘
写一个存储过程,根据班级 ID 删除该班学生
说明函数和存储过程的区别

