Oracle SQL 开发规范
Oracle SQL 开发规范
适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
SQL 开发规范保证代码质量[1]:
详细见:Oracle 数据库设计原则详解。
2. 命名规范
2.1 表
- 单数
- 业务前缀
- 下划线
- < 30 字符
- 示例:emp_employee, ord_order
2.2 列
- 清晰
- 类型后缀(可选)
- 主键:id
- 外键:xxx_id
- 名称:name, title
- 日期:xxx_date
- 金额:xxx_amount
- 状态:status
2.3 对象
| 类型 | 前缀 | 示例 |
|---|---|---|
| 表 | - | employees |
| 视图 | v_ | v_emp_dept |
| 序列 | seq_ | seq_emp |
| 索引 | idx_ | idx_emp_name |
| 主键 | pk_ | pk_employees |
| 唯一 | uk_ | uk_emp_email |
| 外键 | fk_ | fk_emp_dept |
| 检查 | ck_ | ck_emp_salary |
| 非空 | nn_ | nn_emp_name |
| 过程 | sp_ | sp_hire_emp |
| 函数 | fn_ | fn_get_count |
| 包 | pkg_ | pkg_emp |
| 触发器 | trg_ | trg_audit_emp |
| 类型 | t_ / ty_ | t_emp_rec |
| 异常 | e_ | e_invalid_salary |
| 常量 | c_ | c_max_salary |
| 变量 | v_ | v_count |
| 参数 | p_ | p_dept_id |
3. SQL 风格
3.1 关键字大写
SELECT id, name, salary
FROM employees
WHERE dept_id = 10
ORDER BY name;
3.2 缩进
SELECT
e.id,
e.name,
d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.id
WHERE e.status = 'ACTIVE'
AND e.salary > 5000
ORDER BY e.name;
3.3 列对齐
SELECT e.id,
e.name,
e.salary
FROM employees e
WHERE e.dept_id = 10;
3.4 别名
SELECT e.id AS employee_id,
e.name AS employee_name
FROM employees e
JOIN departments d ON e.dept_id = d.id;
4. SELECT
4.1 明确列
-- 好
SELECT id, name, salary FROM employees WHERE id = 100;
-- 差
SELECT * FROM employees WHERE id = 100;
4.2 别名
SELECT e.id AS employee_id,
d.dept_name AS department
FROM employees e, departments d
WHERE e.dept_id = d.id;
5. WHERE
5.1 索引友好
-- 好
SELECT * FROM employees WHERE id = 100;
SELECT * FROM employees WHERE name = 'Alice';
-- 差(函数)
SELECT * FROM employees WHERE UPPER(name) = 'ALICE';
-- 差(计算)
SELECT * FROM employees WHERE salary / 12 > 5000;
-- 好
SELECT * FROM employees WHERE salary > 60000;
5.2 类型匹配
-- 好
SELECT * FROM employees WHERE id = 100;
SELECT * FROM employees WHERE name = 'Alice';
-- 差(隐式转换)
SELECT * FROM employees WHERE id = '100';
SELECT * FROM employees WHERE hire_date = '2025-01-01';
详细见:Oracle SQL 查询优化技巧。
6. JOIN
6.1 现代语法
-- 好
SELECT e.name, d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.id
WHERE e.status = 'ACTIVE';
-- 老式(不推荐)
SELECT e.name, d.dept_name
FROM employees e, departments d
WHERE e.dept_id = d.id AND e.status = 'ACTIVE';
6.2 表别名
SELECT e.name, d.dept_name
FROM employees e
JOIN departments d ON e.dept_id = d.id;
详细见:Oracle JOIN 连接方式。
7. 绑定变量
7.1 PL/SQL
-- 自动绑定
CREATE PROCEDURE get_emp(p_id NUMBER) IS
v_name employees.name%TYPE;
BEGIN
SELECT name INTO v_name FROM employees WHERE id = p_id;
END;
7.2 动态 SQL
-- 好
EXECUTE IMMEDIATE 'SELECT * FROM t WHERE id = :id' USING v_id;
-- 差
EXECUTE IMMEDIATE 'SELECT * FROM t WHERE id = ' || v_id;
7.3 应用
// 好
PreparedStatement ps = con.prepareStatement("SELECT * FROM emp WHERE id = ?");
ps.setInt(1, 100);
// 差
String sql = "SELECT * FROM emp WHERE id = " + 100;
8. PL/SQL
8.1 命名
CREATE OR REPLACE PROCEDURE sp_hire_emp(
p_name IN VARCHAR2,
p_salary IN NUMBER DEFAULT 5000,
p_dept_id IN NUMBER,
p_emp_id OUT NUMBER
) IS
v_count NUMBER;
c_max_salary CONSTANT NUMBER := 100000;
BEGIN
...
EXCEPTION
WHEN OTHERS THEN
...
END;
/
8.2 异常处理
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- 具体处理
WHEN TOO_MANY_ROWS THEN
-- 具体处理
WHEN OTHERS THEN
log_error(...);
RAISE;
END;
详细见:Oracle PL/SQL 异常处理详解。
8.3 性能
-- BULK COLLECT
SELECT * BULK COLLECT INTO v_emp FROM employees LIMIT 1000;
-- FORALL
FORALL i IN 1..v_ids.COUNT
INSERT INTO t VALUES (v_ids(i));
详细见:Oracle BULK COLLECT 与 FORALL 详解。
9. 注释
9.1 表
COMMENT ON TABLE employees IS '员工信息表';
COMMENT ON COLUMN employees.salary IS '员工月薪(元)';
COMMENT ON COLUMN employees.hire_date IS '入职日期';
9.2 代码
-- 单行
/*
多行
说明
*/
CREATE OR REPLACE PROCEDURE sp_hire_emp(
p_name IN VARCHAR2, -- 员工姓名
p_salary IN NUMBER, -- 月薪
p_dept_id IN NUMBER -- 部门ID
) IS
-- 招聘员工
-- Author: xxx
-- Date: 2026-07-21
BEGIN
...
END;
/
10. 事务
10.1 短事务
- 业务开始
- DML
- COMMIT / ROLLBACK
- 业务结束
10.2 一致顺序
- 避免死锁
- 表顺序一致
- 行顺序一致
详细见:Oracle 事务与并发控制详解。
11. 安全
11.1 SQL 注入
-- DBMS_ASSERT
EXECUTE IMMEDIATE 'SELECT * FROM ' || DBMS_ASSERT.QUALIFIED_SQL_NAME(p_table);
-- 绑定变量
EXECUTE IMMEDIATE 'SELECT * FROM t WHERE id = :id' USING v_id;
11.2 最小权限
- 角色
- 视图
- 存储过程
- VPD
12. 性能
12.1 索引
- 高选择性
- 覆盖
- 复合合理
详细见:Oracle 索引优化策略详解。
12.2 执行计划
EXPLAIN PLAN FOR ...;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY));
详细见:Oracle 执行计划详解。
12.3 统计信息
EXEC DBMS_STATS.GATHER_TABLE_STATS(...);
详细见:Oracle SQL 调优最佳实践。
13. 版本控制
13.1 脚本组织
/db
/ddl
/tables
/indexes
/constraints
/dml
/packages
/procedures
/functions
/triggers
/views
/migrations
/V1.0.0
/V1.1.0
13.2 命名
- V1.0.0__create_employees.sql
- V1.1.0__add_email_column.sql
- R__update_dept_data.sql
13.3 工具
- Flyway
- Liquibase
- Git
14. 测试
14.1 单元测试
-- UTPLSQL
CREATE OR REPLACE PROCEDURE test_hire_emp IS
v_id NUMBER;
BEGIN
sp_hire_emp('Alice', 5000, 10, v_id);
ut.expect(v_id).to_be_gt(0);
END;
/
14.2 集成测试
- 端到端
- 业务流程
- 性能
15. 代码审查
15.1 检查项
- 命名规范
- 性能(索引/绑定)
- 安全(注入)
- 异常处理
- 注释
- 测试
15.2 工具
- Code Review
- 静态分析
- SQL Inspector
16. 文档
16.1 数据字典
- 表说明
- 列说明
- 关系
- 约束
16.2 API
- 过程说明
- 参数
- 返回
- 异常
- 示例
17. 常见反模式
17.1 避免
- SELECT *
- 隐式转换
- 函数阻止索引
- OR 性能
- 不必要 DISTINCT
- UNION 改 UNION ALL
- 拼接 SQL
- 全表扫描
- 过度复杂 SQL
17.2 推荐
- 明确列
- 绑定变量
- 索引友好
- 现代语法
- 简单清晰
18. 最佳实践
- 命名规范:一致
- 关键字大写:清晰
- 明确列:性能
- 绑定变量:减少解析
- 现代 JOIN:清晰
- 异常处理:完整
- 注释:说明
- 版本控制:管理
- 测试:验证
- 审查:质量
19. 参考资料
[1] Oracle Database SQL Tuning Guide 19c https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/