Oracle存储过程怎么写

Oracle 存储过程(Stored Procedure)是存储在数据库中的一组预编译 SQL 和 PL/SQL 代码块,用于封装复杂的业务逻辑。

以下是完整的编写指南,包含基本结构参数类型常用逻辑 以及完整示例

1. 基本语法结构

一个标准的存储过程由三部分组成:声明部分执行部分异常处理部分

sql 复制代码
CREATE OR REPLACE PROCEDURE 过程名 (
    参数1 IN 数据类型,      -- 输入参数
    参数2 OUT 数据类型,     -- 输出参数
    参数3 IN OUT 数据类型   -- 输入输出参数
) IS
    -- 【声明部分】定义局部变量、游标、常量等
    v_variable_name  VARCHAR2(100);
    v_count          NUMBER := 0;
BEGIN
    -- 【执行部分】编写具体的 SQL 和业务逻辑
    SELECT count(*) INTO v_count FROM 表名 WHERE 条件;
    
    IF v_count > 0 THEN
        -- 业务逻辑...
        参数2 := '成功'; -- 给输出参数赋值
    ELSE
        参数2 := '失败';
    END IF;

EXCEPTION
    -- 【异常处理部分】捕获并处理错误
    WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE('未找到数据');
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('发生错误: ' || SQLERRM);
END 过程名;

2. 三种参数模式

模式 关键字 说明 使用场景
输入 IN 默认模式。调用时传入值,过程内只读。 查询条件、配置值。
输出 OUT 调用时需传入变量接收返回值,过程内可赋值。 返回统计结果、状态码、生成的主键ID。
输入输出 IN OUT 传入初始值,过程处理后修改该值并返回。 累加计算、字符串拼接处理。

3. 实战示例:用户信息处理

假设有一个表 USERS (ID, NAME, AGE, CITY)。我们要写一个存储过程:

  1. 根据 ID 查询用户。
  2. 如果用户年龄大于 18 岁且城市包含"市",则去掉城市后缀(类似你之前的 JS 逻辑)。
  3. 返回处理后的城市和状态消息。
sql 复制代码
CREATE OR REPLACE PROCEDURE PROC_UPDATE_USER_CITY (
    p_user_id   IN  NUMBER,           -- 输入:用户ID
    p_city_out  OUT VARCHAR2,         -- 输出:处理后的城市
    p_msg       OUT VARCHAR2          -- 输出:执行消息
) IS
    v_age       NUMBER;
    v_city      VARCHAR2(100);
    v_name      VARCHAR2(100);
BEGIN
    -- 1. 查询数据
    SELECT age, city, name 
    INTO v_age, v_city, v_name
    FROM USERS 
    WHERE id = p_user_id;

    -- 2. 业务逻辑判断
    IF v_age > 18 THEN
        -- 模拟去除城市后缀逻辑
        IF INSTR(v_city, '市') > 0 AND v_city NOT LIKE '%自治州%' THEN
            v_city := REPLACE(v_city, '市', '');
        END IF;
        
        p_msg := '用户 ' || v_name || ' 处理成功,新城市为:' || v_city;
    ELSE
        p_msg := '用户未成年,不处理城市信息。';
    END IF;

    -- 3. 赋值给输出参数
    p_city_out := v_city;

EXCEPTION
    WHEN NO_DATA_FOUND THEN
        p_msg := '错误:未找到 ID 为 ' || p_user_id || ' 的用户';
        p_city_out := NULL;
    WHEN OTHERS THEN
        p_msg := '系统异常:' || SQLERRM;
        p_city_out := NULL;
        -- 可选:记录日志到日志表
        -- INSERT INTO error_log VALUES (SYSDATE, SQLERRM);
END PROC_UPDATE_USER_CITY;

4. 如何调用存储过程

方法 A:在 SQL Developer / PLSQL Developer 中测试
sql 复制代码
DECLARE
    v_result_city VARCHAR2(100);
    v_message     VARCHAR2(200);
BEGIN
    -- 调用过程
    PROC_UPDATE_USER_CITY(
        p_user_id   => 1001,          -- 传入具体值
        p_city_out  => v_result_city, -- 传入变量接收
        p_msg       => v_message
    );
    
    -- 打印结果
    DBMS_OUTPUT.PUT_LINE(v_message);
    DBMS_OUTPUT.PUT_LINE('处理后城市:' || v_result_city);
END;

注意:使用前需开启输出显示 SET SERVEROUTPUT ON;

方法 B:在 Java / Python / Kettle 中调用
  • Java (JDBC): 使用 CallableStatement
  • Kettle: 使用 "Call DB Procedure" 组件,选择刚才创建的过程名,映射输入输出参数即可。

5. 常用技巧与注意事项

  1. CREATE OR REPLACE :

    • 始终加上 OR REPLACE,这样如果过程已存在,会直接覆盖更新,而不会报错。
  2. 变量赋值 :

    • 使用 := 进行赋值(如 v_count := 1;)。
    • 使用 SELECT ... INTO ... 将查询结果赋给变量。
  3. 动态 SQL :

    • 如果表名或列名需要动态变化,使用 EXECUTE IMMEDIATE
    sql 复制代码
    EXECUTE IMMEDIATE 'UPDATE ' || v_table_name || ' SET status=1 WHERE id=:1' USING p_id;
  4. 事务控制 :

    • 存储过程内部通常不写 COMMITROLLBACK,除非明确设计为独立事务。最好由调用者(外部程序)决定何时提交事务,以保持灵活性。
  5. 调试 :

    • 使用 DBMS_OUTPUT.PUT_LINE('变量值:' || v_var); 打印调试信息。

6. 常见错误排查

  • ORA-06550 / PLS-00201: 标识符必须声明(检查变量名拼写,或是否有权限访问该表)。
  • ORA-01403 : 未找到数据(SELECT INTO 没查到数据,需在 EXCEPTION 中捕获 NO_DATA_FOUND)。
  • ORA-01422 : 返回多于请求的行数(SELECT INTO 查出了多行,但变量只能存一行,需改用游标 CURSOR)。

如果你需要将之前 Kettle 中的 JavaScript 清洗逻辑迁移到 Oracle 存储过程中,我可以帮你直接转换那段代码。

相关推荐
搜佛说2 小时前
第2章-EdgeX-Foundry架构深度解析
数据库·物联网·架构·边缘计算·iot
知识分享小能手2 小时前
PostgreSQL 入门学习教程,从入门到精通,PostgreSQL 16 服务器配置与数据库监控终极指南 —语法、案例与实战(18)
数据库·学习·postgresql
珠海西格电力2 小时前
零碳园区全面感知体系的建设成本和收益分析包含哪些关键数据?
大数据·数据库·人工智能·智慧城市·能源
天空属于哈夫克32 小时前
私域自动化:构建企业微信全链路无人值守运营体系
数据库
wangjinxun2 小时前
【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库
数据库·mysql·数据库开发
sa100272 小时前
获取京东评论api接口
数据库
l1t2 小时前
直接case when 聚合和先聚合后case when在duckdb150和sqlite3.52的性能比较
数据库·sqlite·duckdb
爆炒西瓜@2 小时前
springboot内存定位,提取数据库账号密码
数据库·spring boot·后端
数据知道3 小时前
MongoDB分片集群部署:详细生产环境完整搭建
数据库·mongodb