跳转至

PL/SQL 新人注意事项、常见错误与面试问题

本章作为 PL/SQL 教程的收官章节,不再新增语法,而是系统总结:

  • 新人最容易踩的坑
  • 项目中最常见、最危险的错误
  • 面试中 真正会被问到、并区分水平的题目

这一章的目标只有一个:

👉 让新人少犯错、让面试回答“像做过项目的人”


1. 新人最容易混淆的核心认知

1.1 把 PL/SQL 当成“增强版 SQL”

❌ 错误认知:

SQL 不够强,所以用 PL/SQL 来补

✅ 正确认知:

  • SQL:集合运算、数据处理
  • PL/SQL:流程控制、组织 SQL

📌 原则:

能用一条 SQL 解决的,绝不用 PL/SQL 循环


1.2 忽视 SQL 与 PL/SQL 的上下文切换

❌ 常见写法:

for r in (select * from big_table) loop
  update big_table set ... where id = r.id;
end loop;

问题:

  • 性能极差

✅ 正确方向:

  • BULK COLLECT + FORALL

2. 新人高频致命错误(项目级)

2.1 吞异常(最危险)

❌ 错误示例:

exception
  when others then
    null;

后果:

  • 错误被隐藏
  • 数据不一致
  • 无法排查生产事故

✅ 正确原则:

  • 已知异常明确处理
  • 未知异常必须抛出

2.2 错误的 COMMIT 位置

❌ 错误示例:

for i in 1..1000 loop
  update ...;
  commit;
end loop;

问题:

  • 性能差
  • 数据难以回滚

✅ 正确做法:

  • 批量处理后统一 COMMIT
  • 或 LIMIT 分批 COMMIT

2.3 在在线事务中让 PL/SQL COMMIT

❌ 场景:

  • Java + Spring 调用存储过程
  • 存储过程内部 COMMIT

后果:

  • Java 事务失效
  • 数据出现“半成功”

✅ 原则:

在线事务中,COMMIT 永远由 Java 控制


2.4 NULL 判断错误

❌ 错误写法:

if v_val = null then

✅ 正确写法:

if v_val is null then

📌 延伸:

  • SQL 是三值逻辑(TRUE / FALSE / UNKNOWN)

3. 性能相关的新人误区

3.1 认为 BULK 一定更快

❌ 误区:

BULK COLLECT 一定比游标快

✅ 实际情况:

  • 小数据量:游标更简单
  • 大数据量:BULK 明显更快

📌 关键在于:

数据量 + 内存 + 业务复杂度


3.2 忽视 LIMIT

❌ 错误示例:

select * bulk collect into v_rows from huge_table;

风险:

  • PGA 内存爆炸

✅ 正确做法:

  • BULK + LIMIT 分批

4. PACKAGE 使用方面的常见问题

4.1 不用 PACKAGE,过程到处散落

问题:

  • 无命名空间
  • 权限难控
  • 维护困难

✅ 项目原则:

核心业务逻辑必须封装在 PACKAGE 中


4.2 在 PACKAGE SPEC 中暴露太多东西

❌ 错误做法:

  • 把所有过程都写进 SPEC

✅ 正确做法:

  • SPEC 只暴露接口
  • BODY 隐藏实现

5. 批处理相关常见错误

5.1 批处理不能重跑

❌ 问题设计:

  • 无状态字段
  • 无批次号

后果:

  • 一旦失败只能手工修数据

✅ 正确设计:

  • 状态控制
  • 幂等设计

5.2 没有日志表

❌ 只用 dbms_output

问题:

  • 生产环境不可见

✅ 必须:

  • 日志表 + 自治事务

6. 面试高频问题(带答题思路)

Q1:PL/SQL 中游标和 BULK COLLECT 的区别?

答题思路:

  • SQL 执行方式一样
  • 区别在数据返回方式
  • 上下文切换次数不同

Q2:存储过程里能不能 COMMIT?

答题思路:

  • 在线事务不允许
  • 批处理允许
  • 触发器不允许

Q3:为什么项目中要用 PACKAGE?

答题思路:

  • 接口与实现分离
  • 权限控制
  • 性能

Q4:批处理失败了怎么办?

答题思路:

  • 支持重跑
  • 日志定位
  • 幂等设计

Q5:如何避免 PL/SQL 性能问题?

关键词:

  • 减少上下文切换
  • BULK / FORALL
  • 合理 COMMIT

7. 新人到熟练工程师的关键转变

阶段 特点
新人 会写语法
熟练 知道风险
高级 能提前规避

8. 全书总结(一句话)

PL/SQL 不是写得多,而是写得稳、跑得久、不出事。


9. 本章 & 全教程结语

如果你能完整理解并实践:

  • PACKAGE
  • 异常设计
  • 批量处理
  • 事务边界

那么你已经:

✅ 不是“只会写 PL/SQL 的新人”,

而是 能在真实项目中承担责任的工程师