1. Oracle SQL操作实战指南
作为从业15年的数据库管理员,我整理了Oracle数据库日常开发和管理中最实用的SQL语句集。这些语句经过生产环境验证,能解决80%的常规需求,特别适合刚接触Oracle的开发者快速上手。
2. 基础查询与数据操作
2.1 核心查询语句
-- 基础查询(带分页)
SELECT * FROM (
SELECT t.*, ROWNUM rn
FROM employees t
WHERE ROWNUM <= 20
) WHERE rn > 10;
-- 条件查询(NVL处理空值)
SELECT employee_id, NVL(commission_pct, 0)
FROM employees
WHERE department_id = 50;
注意:Oracle分页必须使用ROWNUM嵌套查询,直接WHERE ROWNUM BETWEEN 11 AND 20会返回空结果
2.2 数据修改操作
-- 批量更新(使用MERGE替代UPDATE)
MERGE INTO employees e
USING (SELECT employee_id, salary*1.1 new_sal FROM employees WHERE department_id=60) s
ON (e.employee_id = s.employee_id)
WHEN MATCHED THEN UPDATE SET e.salary = s.new_sal;
-- 带条件删除
DELETE FROM order_details
WHERE order_id IN (
SELECT order_id FROM orders
WHERE order_date < ADD_MONTHS(SYSDATE, -24)
);
3. 高级查询技巧
3.1 分析函数应用
-- 部门工资排名
SELECT
employee_id,
department_id,
salary,
RANK() OVER(PARTITION BY department_id ORDER BY salary DESC) dept_rank
FROM employees;
-- 移动平均值计算
SELECT
product_id,
sale_date,
amount,
AVG(amount) OVER(
PARTITION BY product_id
ORDER BY sale_date
RANGE BETWEEN INTERVAL '7' DAY PRECEDING AND CURRENT ROW
) weekly_avg
FROM sales;
3.2 递归查询
-- 组织层级查询
WITH org_hierarchy AS (
-- 基础查询(顶级节点)
SELECT employee_id, manager_id, 1 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- 递归部分
SELECT e.employee_id, e.manager_id, h.level + 1
FROM employees e
JOIN org_hierarchy h ON e.manager_id = h.employee_id
)
SELECT * FROM org_hierarchy;
4. 系统管理与性能优化
4.1 空间管理
-- 表空间使用监控
SELECT
tablespace_name,
ROUND(used_space/1024/1024,2) used_mb,
ROUND(tablespace_size/1024/1024,2) total_mb,
ROUND(used_percent,2) pct_used
FROM dba_tablespace_usage_metrics;
-- 重建索引(解决碎片化)
ALTER INDEX idx_employee_name REBUILD ONLINE;
4.2 SQL性能分析
-- 查看执行计划
EXPLAIN PLAN FOR
SELECT * FROM orders WHERE customer_id = 100;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- 查找高负载SQL
SELECT
sql_id,
executions,
ROUND(elapsed_time/1000000) total_sec,
ROUND(elapsed_time/1000000/NULLIF(executions,0),4) sec_per_exec
FROM v$sqlarea
ORDER BY elapsed_time DESC
FETCH FIRST 10 ROWS ONLY;
5. 数据字典查询
5.1 元数据查询
-- 查看表结构
SELECT
column_name,
data_type,
data_length,
nullable
FROM all_tab_columns
WHERE table_name = 'EMPLOYEES';
-- 查找外键关系
SELECT
a.table_name child_table,
a.constraint_name,
c_pk.table_name parent_table
FROM all_constraints a
JOIN all_constraints c_pk ON a.r_constraint_name = c_pk.constraint_name
WHERE a.constraint_type = 'R'
AND a.table_name = 'ORDER_DETAILS';
6. 实战经验分享
6.1 批量数据处理技巧
-- 使用FORALL加速DML(PL/SQL示例)
DECLARE
TYPE id_array IS TABLE OF NUMBER;
v_ids id_array := id_array(101,102,103,104);
BEGIN
FORALL i IN 1..v_ids.COUNT
UPDATE employees
SET salary = salary * 1.05
WHERE employee_id = v_ids(i);
COMMIT;
END;
/
-- 数据泵替代传统导出(命令行)
expdp system/password DIRECTORY=data_pump_dir
DUMPFILE=employees.dmp TABLES=hr.employees
6.2 常见问题解决方案
-- 解决ORA-01555快照过旧错误
ALTER TABLE transactions MODIFY
PCTFREE 10 PCTUSED 40
INITRANS 4;
-- 处理锁冲突
SELECT
session_id,
oracle_username,
object_name,
locked_mode
FROM v$locked_object lo
JOIN dba_objects do ON lo.object_id = do.object_id;
7. 安全与审计
7.1 权限管理
-- 创建角色并授权
CREATE ROLE report_viewer;
GRANT SELECT ON hr.employees TO report_viewer;
GRANT SELECT ON hr.departments TO report_viewer;
-- 查看用户权限
SELECT * FROM dba_sys_privs WHERE grantee = 'HR';
7.2 审计配置
-- 启用标准审计
AUDIT SELECT TABLE, UPDATE TABLE BY hr;
-- 查看审计记录
SELECT
username,
action_name,
timestamp
FROM dba_audit_trail
WHERE obj_name = 'SALARY_DATA'
ORDER BY timestamp DESC;
8. 特殊场景处理
8.1 分区表维护
-- 添加新分区
ALTER TABLE sales_data
ADD PARTITION p_2024 VALUES LESS THAN (TO_DATE('2025-01-01','YYYY-MM-DD'));
-- 合并历史分区
ALTER TABLE sales_data
MERGE PARTITIONS p_2022, p_2023 INTO p_2022_2023;
8.2 大对象处理
-- 导出CLOB到文件(UTL_FILE示例)
DECLARE
v_clob CLOB;
v_file UTL_FILE.FILE_TYPE;
BEGIN
SELECT document_content INTO v_clob
FROM contracts WHERE contract_id = 1001;
v_file := UTL_FILE.FOPEN('DOC_DIR','contract.txt','W');
UTL_FILE.PUT_LINE(v_file, v_clob);
UTL_FILE.FCLOSE(v_file);
END;
/
-- 压缩大表
ALTER TABLE archive_data COMPRESS FOR OLTP;
在12.2c版本后,推荐使用在线DDL操作减少锁等待:
ALTER TABLE employees MODIFY (email VARCHAR2(100)) ONLINE;
实际项目中我发现,定期收集统计信息能显著提升复杂查询性能:
-- 夜间作业收集统计信息
BEGIN
DBMS_STATS.GATHER_SCHEMA_STATS(
ownname => 'HR',
estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO',
degree => DBMS_STATS.AUTO_DEGREE
);
END;
/

1699

被折叠的 条评论
为什么被折叠?



