导读:本期聚焦于小伙伴创作的《Oracle数据库存储过程是什么,怎么创建和使用?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Oracle数据库存储过程是什么,怎么创建和使用?》有用,将其分享出去将是对创作者最好的鼓励。

Oracle数据库存储过程是一组为了完成特定功能的PL_SQL语句集合,经编译后存储在数据库中,用户可以通过指定存储过程的名字并给出参数来执行它。存储过程可以接收输入参数、返回输出参数,也能包含复杂的业务逻辑判断、循环操作等,适合处理需要多次执行的批量数据操作、复杂业务规则校验等场景。

Oracle数据库存储过程是什么,怎么创建和使用?

Oracle存储过程的核心优势

使用存储过程相比直接执行零散SQL语句有不少优势:

  • 提升执行效率:存储过程在首次执行时会被编译并缓存执行计划,后续调用无需重复编译,减少解析开销。
  • 减少网络传输:只需要传递存储过程名称和参数,不需要传输大量SQL语句,降低网络压力。
  • 代码复用性高:封装好的逻辑可以被多个应用、多个业务模块重复调用,避免重复编写相同代码。
  • 安全性更好:可以给用户授予存储过程的执行权限,而不用直接开放底层表的操作权限,降低数据误操作风险。

创建存储过程的基本语法

创建存储过程使用CREATE OR REPLACE PROCEDURE语句,基本结构如下:

-- 创建存储过程基本语法
CREATE OR REPLACE PROCEDURE 存储过程名称(
    -- 输入参数,IN可以省略,默认是输入参数
    参数名1 IN 参数类型,
    参数名2 IN 参数类型,
    -- 输出参数,需要显式声明OUT
    参数名3 OUT 参数类型
) AS
    -- 声明局部变量
    局部变量名 变量类型;
BEGIN
    -- 业务逻辑代码
    -- 可以给输出参数赋值
    参数名3 := 计算结果;
    -- 可以执行DML操作
    INSERT INTO 表名(列1,列2) VALUES(参数名1,参数名2);
    COMMIT;
EXCEPTION
    -- 异常处理逻辑
    WHEN OTHERS THEN
        ROLLBACK;
        RAISE;
END 存储过程名称;

存储过程使用示例

无参存储过程示例

下面创建一个简单的无参存储过程,实现向测试表插入一条固定数据:

-- 先创建测试表
CREATE TABLE test_proc_table(
    id NUMBER PRIMARY KEY,
    content VARCHAR2(50),
    create_time DATE
);

-- 创建无参存储过程
CREATE OR REPLACE PROCEDURE proc_insert_test_data AS
    v_max_id NUMBER;
BEGIN
    -- 查询当前最大id
    SELECT NVL(MAX(id),0) INTO v_max_id FROM test_proc_table;
    -- 插入新数据
    INSERT INTO test_proc_table(id,content,create_time)
    VALUES(v_max_id + 1, '存储过程插入的数据', SYSDATE);
    COMMIT;
    DBMS_OUTPUT.PUT_LINE('数据插入成功,新增id为:' || (v_max_id + 1));
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
        DBMS_OUTPUT.PUT_LINE('插入失败,错误原因:' || SQLERRM);
        RAISE;
END proc_insert_test_data;

带输入输出参数的存储过程示例

创建一个根据部门编号查询部门员工总数的存储过程,输入部门编号,输出员工总数:

-- 假设存在员工表emp,包含deptno(部门编号)列
CREATE OR REPLACE PROCEDURE proc_get_emp_count(
    p_deptno IN NUMBER,  -- 输入参数:部门编号
    p_emp_count OUT NUMBER  -- 输出参数:员工总数
) AS
BEGIN
    -- 查询指定部门的员工数量
    SELECT COUNT(*) INTO p_emp_count FROM emp WHERE deptno = p_deptno;
    DBMS_OUTPUT.PUT_LINE('部门' || p_deptno || '的员工总数为:' || p_emp_count);
EXCEPTION
    WHEN OTHERS THEN
        p_emp_count := -1;  -- 异常时返回-1表示查询失败
        DBMS_OUTPUT.PUT_LINE('查询失败,错误原因:' || SQLERRM);
        RAISE;
END proc_get_emp_count;

存储过程的调用方式

在PL_SQL块中调用

在PL_SQL开发工具中,可以直接使用匿名块调用存储过程:

-- 调用无参存储过程
BEGIN
    proc_insert_test_data;
END;
/

-- 调用带参数的存储过程
DECLARE
    v_count NUMBER;
BEGIN
    proc_get_emp_count(10, v_count);  -- 查询10号部门的员工数
    IF v_count != -1 THEN
        DBMS_OUTPUT.PUT_LINE('调用结果:员工数为' || v_count);
    END IF;
END;
/

在JDBC中调用

Java程序通过JDBC调用存储过程的示例如下:

import java.sql.*;

public class CallOracleProc {
    public static void main(String[] args) {
        String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
        String user = "test";
        String password = "test123";
        Connection conn = null;
        CallableStatement cs = null;
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            conn = DriverManager.getConnection(url, user, password);
            // 调用带输入输出参数的存储过程,?是占位符
            cs = conn.prepareCall("{call proc_get_emp_count(?, ?)}");
            // 设置输入参数
            cs.setInt(1, 20);
            // 注册输出参数类型
            cs.registerOutParameter(2, Types.NUMERIC);
            // 执行存储过程
            cs.execute();
            // 获取输出参数结果
            int empCount = cs.getInt(2);
            System.out.println("20号部门员工总数:" + empCount);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (cs != null) cs.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

存储过程的修改与删除

修改存储过程

如果需要修改存储过程的逻辑,不需要先删除再创建,直接使用CREATE OR REPLACE PROCEDURE语句重新编译即可,Oracle会自动替换原有存储过程:

-- 修改之前的proc_insert_test_data存储过程,增加插入内容的前缀
CREATE OR REPLACE PROCEDURE proc_insert_test_data AS
    v_max_id NUMBER;
BEGIN
    SELECT NVL(MAX(id),0) INTO v_max_id FROM test_proc_table;
    INSERT INTO test_proc_table(id,content,create_time)
    VALUES(v_max_id + 1, '修改后:存储过程插入的数据', SYSDATE);
    COMMIT;
    DBMS_OUTPUT.PUT_LINE('数据插入成功,新增id为:' || (v_max_id + 1));
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
        DBMS_OUTPUT.PUT_LINE('插入失败,错误原因:' || SQLERRM);
        RAISE;
END proc_insert_test_data;

删除存储过程

删除存储过程使用DROP PROCEDURE语句:

-- 删除存储过程
DROP PROCEDURE proc_insert_test_data;

存储过程常见问题与注意事项

  • 存储过程中的DML操作需要注意事务控制,要么显式提交要么回滚,避免出现事务悬挂问题。
  • 参数类型不要指定长度,比如声明参数时写VARCHAR2即可,不需要写VARCHAR2(50),长度由调用时传入的值决定。
  • 调试存储过程可以使用DBMS_OUTPUT输出日志,或者使用Oracle自带的企业管理器、PL_SQL Developer等工具的调试功能。
  • 存储过程名不要和数据库中的表名、视图名重名,避免调用时出现歧义。
  • 如果存储过程需要返回多个结果集,可以结合游标类型参数实现,将游标作为输出参数传递给调用方。

Oracle存储过程PL_SQL数据库编程修改时间:2026-06-17 10:42:54

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。