ORACLE数据库里那些过程和函数到底咋用,讲得透彻点儿给你听
- 问答
- 2025-12-25 11:31:42
- 3
它俩到底是啥?为啥要用它?
想象一下,你每天都要做一道复杂的菜,红烧肉”,每次做,你都得重新回忆步骤:先切肉、焯水、炒糖色、下锅炖……反反复复,很麻烦,如果你有个菜谱(过程),或者干脆把关键的调味汁提前调好放冰箱(函数),下次直接用,是不是就省事儿多了?
在ORACLE数据库里:
- 存储过程:就像那份完整的“红烧肉菜谱”,它是一组为了完成特定功能的SQL语句集合,你给它一些原料(比如猪肉、调料),它就能帮你把整个做菜流程走完,它更侧重于“做一件事”这个动作本身,不一定要有直接的结果给你,它可能负责把新员工的信息插入好几个相关的表格里,这是一个完整的流程。
- 函数:更像你提前调好的“秘制红烧汁”,它也是一段代码,但它核心目的是“计算并返回一个值”,你给它酱油、糖、料酒(输入参数),它混合一下,返回一碗调好的汁给你,函数必须有一个明确的返回值。
为啥要用它们?(来源:基于常见的数据库开发实践总结)
- 提高效率:菜谱写好了,就不用每次都重新想步骤,数据库也一样,过程和函数编译一次后,数据库就知道怎么执行了,下次直接用,速度快。
- 减少网络流量:假设你的程序在另一台电脑上,要执行十条SQL语句才能完成一个业务,如果没有过程,你得在网络上发送十次请求,但如果把这十条SQL打包成一个过程,你只需要调用一次这个过程名,网络上传送的数据量就小多了。
- 方便维护和重用:业务逻辑变了,比如红烧肉以后要加新调料了,你只需要修改“菜谱”(过程)这一处地方就行了,所有调用这个菜谱的程序就都自动用了新方法,不用到成千上万个程序里一个一个去改。
- 数据安全:你可以只给用户执行某个过程的权限,而不让他直接操作底层的数据表,你可以让用户通过“申请报销”这个过程来插入数据,但他没法直接去修改报销金额这个字段,更安全。
过程和函数具体咋创建和使用?
存储过程
-
创建过程(语法来源:ORACLE官方文档CREATE PROCEDURE语句的精简概括)
基本套路是:
CREATE OR REPLACE PROCEDURE 过程名 (参数1 模式 数据类型, 参数2 模式 数据类型, ...) IS -- 这里可以声明一些变量,就像做菜前准备的碗碟 BEGIN -- 这里写核心的SQL语句,你的菜谱步骤 -- INSERT, UPDATE, DELETE, SELECT ... INTO 等 END;注意那个“模式”:
- IN:默认模式,输入参数”,你传给过程的“原料”,过程内部只能用,不能改。
- OUT:输出参数,过程做完事后,通过这个参数把结果“带出来”给你,过程内部可以修改它的值。
- IN OUT:既能当输入,也能当输出。
-
举个栗子(例子来源:常见的业务场景模拟) 我们创建一个给员工涨工资的过程:
CREATE OR REPLACE PROCEDURE raise_salary ( p_emp_id IN employees.employee_id%TYPE, -- 输入参数:员工ID,类型和employees表的employee_id字段一样 p_amount IN NUMBER -- 输入参数:涨薪金额 ) IS BEGIN -- 菜谱步骤:更新工资 UPDATE employees SET salary = salary + p_amount WHERE employee_id = p_emp_id; -- 提交事务(也可以在主程序里提交) COMMIT; DBMS_OUTPUT.PUT_LINE('员工 ' || p_emp_id || ' 涨薪成功!'); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('找不到该员工!'); END raise_salary; -
调用过程:
-- 在SQLPLUS或者能输出信息的环境下 BEGIN raise_salary(100, 500); -- 给ID为100的员工涨500块钱 END;
函数
-
创建函数(语法来源:ORACLE官方文档CREATE FUNCTION语句的精简概括)
和过程很像,关键区别是必须用RETURN子句声明返回类型,并且函数体内一定要有RETURN语句返回一个值。
CREATE OR REPLACE FUNCTION 函数名 (参数1 IN 数据类型, ...) RETURN 数据类型 IS -- 变量声明 结果变量 数据类型; BEGIN -- 计算逻辑 SELECT ... INTO 结果变量 ... ; -- 常见操作 RETURN 结果变量; -- 必须要有! END; -
举个栗子 创建一个函数,根据部门ID计算该部门的平均工资:
CREATE OR REPLACE FUNCTION get_avg_salary (p_dept_id IN NUMBER) RETURN NUMBER IS v_avg_sal NUMBER; BEGIN SELECT AVG(salary) INTO v_avg_sal FROM employees WHERE department_id = p_dept_id; RETURN NVL(v_avg_sal, 0); -- 如果部门没人,平均工资为NULL,用NVL转为0 END get_avg_salary; -
调用函数: 函数因为有返回值,所以用法灵活得多,可以像使用一个值一样用它。
-- 在SQL语句中直接使用 SELECT department_id, get_avg_salary(department_id) as 部门平均工资 FROM departments; -- 在PL/SQL块中赋值给变量 DECLARE avg_sal NUMBER; BEGIN avg_sal := get_avg_salary(60); DBMS_OUTPUT.PUT_LINE('平均工资是:' || avg_sal); END;
过程和函数的核心区别总结
- 返回值:函数必须有且只有一个返回值,像
get_avg_salary返回一个数字。过程没有返回值,但可以通过OUT参数返回多个值。 - 用法:因为上述区别,函数主要用在表达式里,能出现在SQL语句中SELECT后面、WHERE条件里等,当成一个值来用,而过程是作为一个独立的PL/SQL语句被调用,用
CALL或者直接在BEGIN...END块里写名字执行。 - 目的:函数目的就是计算,然后给你一个结果。过程目的则是执行一个完整的业务操作,可能涉及增删改查多条语句,更像一个“动作”。
简单记:你想得到一个结果(比如算个数、查个状态),用函数,你想完成一个事情(比如审批流程、生成报表数据),用过程。
希望这个“厨房菜谱”的比喻能帮你把这俩家伙看得透透的,核心就是封装和重用,让数据库帮你干复杂的活儿,你的应用程序就轻松了。

本文由邝冷亦于2025-12-25发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/68138.html
