ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Oracle 11g实战源码包:可调试、可验证、开箱即用的活体教材

Oracle 11g实战源码包:可调试、可验证、开箱即用的活体教材

简介:本资源是《Oracle 11g从入门到精通(第二版)》配套的完整实例源程序包,专为数据库初学者、SQL开发人员及DBA入门者设计,旨在通过可运行代码深化对Oracle核心机制的理解与实操能力。压缩包共495个文件,涵盖236个SQL脚本(.txt)、123个编译类文件(.class)、44个Java源码(.java)、36个配置与元数据XML文件,以及JPG图示、备份脚本(.bak)、数据泵导出文件(.dmp)等,全面支撑19章内容的学习验证——从基础安装、SQL查询与索引创建,到视图/存储过程/触发器开发,再到用户权限管理、RMAN备份恢复、分区表与SQL调优等进阶主题。1.21MB轻量级包体便于快速下载与本地部署。目前已有405人学习下载,所有脚本均按章节组织,命名规范、注释清晰,支持开箱即用式验证与调试,是系统掌握Oracle 11g体系化知识不可多得的实践载体。

1. 这不是一本“翻完就扔”的Oracle书:它把11g的安装、建库、SQL调优、PL/SQL调试全塞进了可运行的源程序包里

你有没有试过照着Oracle入门书敲命令,结果卡在“监听启动失败”上一整个下午?或者写完一个存储过程,执行时报 ORA-00942 表不存在,却找不到书中对应示例的建表语句?《oracle11g从入门到精通(第二版)》配套的这个.rar包,根本不是扫描件附录里的截图代码,而是一套真实可解压、可导入、可单步调试的完整工程集合——它包含第3章用户权限管理的create_user.sql和grant_role.sql脚本;第7章事务控制的savepoint_demo.sql和带异常处理的transfer_money.prc;第12章性能优化的awr_report_gen.sql和sql_tuning_advisor_run.sql。所有脚本均适配 Oracle 11g R2(11.2.0.4 及以上),路径层级清晰(/ch05_ddl/,/ch09_plsql/,/ch13_backup/),连tnsnames.ora和listener.ora的最小化配置模板都已预置。适合刚装好 Oracle VirtualBox 虚拟机、正对着 SQL*Plus 黑窗口发懵的初学者,也适合需要快速复现书中索引失效场景、验证执行计划变化的中级 DBA。别再复制粘贴网页碎片了——这次,你拿到的是能直接@进去跑出结果的“活体教材”。

2. 解压即用:从 RAR 包结构到 SQL*Plus 环境的三步落地法

这本书的源程序包不是 ZIP,是.rar格式,这意味着你必须先确认解压工具支持 RAR5(WinRAR 6.0+ 或 7-Zip 21.07+)。很多新手栽在第一步:用老版本 7-Zip 解压后发现ch10_security/目录下全是乱码文件名。这不是编码问题,而是 RAR5 默认启用 UTF-8 文件名存储,旧工具读取时会错解为 GBK。我们来走通从解压到执行的完整链路。

2.1 解压与目录结构验证:别跳过 checksum 校验

先用命令行工具做基础校验(Windows PowerShell):

# 进入下载目录,计算 SHA256 值(官方配套包应为 e3a8f1d2... 开头) Get-FileHash .\oracle11g从入门到精通(第二版)-(实例源程序).rar -Algorithm SHA256 # 解压到干净目录(严禁解压到 C:\oracle\product\11.2.0\dbhome_1\ 下!) & "C:\Program Files\7-Zip\7z.exe" x ".\oracle11g从入门到精通(第二版)-(实例源程序).rar" -o"D:\oracle11g_examples" -y

提示:解压目标路径禁止含中文空格或括号。若你解压到D:\我的文档\Oracle例子\,后续 SQL*Plus 执行@D:\我的文档\Oracle例子\ch03_user\create_user.sql会报SP2-0310: unable to open file。这是 Oracle 客户端对路径中特殊字符的硬性限制,不是权限问题。

解压后你会看到标准的章节目录树:

目录路径关键内容典型用途
/ch02_install/oracle_env_setup.bat,dbca_response.rsp自动化静默建库响应文件,修改GDBNAME=orcl11g即可复用
/ch06_dml/insert_batch.sql,merge_demo.sql演示BULK COLLECT与FORALL的性能对比,含SET TIMING ON计时标记
/ch09_plsql/debug_pkg.pks,debug_pkg.pkb包规范与包体分离,DEBUG_PKG.PRINT_TRACE是书中第9.4节调试技巧的实现实例
/ch11_index/index_test_case.sql,explain_plan_check.sql创建测试表T_INDEX_TEST并强制走不同索引路径,/*+ INDEX(t IDX_T_NAME) */注释已写死

注意:所有.sql文件默认以 UTF-8 BOM 编码保存。若你用记事本修改后保存,务必选“UTF-8”而非“ANSI”,否则中文注释会变乱码,SQL*Plus 会报ORA-00911: invalid character。

2.2 SQL*Plus 环境初始化:绕过 TNSNAMES 配置的直连方案

书中第4章讲 TNS 配置,但新手常因listener.ora端口冲突卡住。其实所有脚本都支持Easy Connect 语法直连,无需配置网络服务名:

-- 在 SQL*Plus 中执行(替换 your_password 和主机IP) CONNECT system/your_password@//192.168.56.101:1521/orcl11g -- 验证连接(书中第4.2节的 SELECT * FROM v$version; 就在这里) SELECT banner FROM v$version WHERE rownum = 1; -- 输出应为:Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

关键参数说明://IP:PORT/SID中的SID必须与你的数据库实例名一致(默认orcl,但书中示例库多为orcl11g)。若不确定,登录服务器后执行ps -ef | grep pmon,输出ora_pmon_orcl11g即表示 SID 是orcl11g。

2.3 批量执行脚本:用 @ 符号链式调用,避免手动复制粘贴

不要把ch05_ddl/create_table.sql内容全选复制进 SQL*Plus——这极易因换行符丢失导致ORA-00922: missing or invalid option。正确做法是:

-- 进入 SQL*Plus 后,先设置输出格式(书中第5.3节要求的列宽控制) SET LINESIZE 200 SET PAGESIZE 100 COLUMN table_name FORMAT A30 -- 使用 @ 符号执行(路径用正斜杠 /,Windows 下也有效) @D:/oracle11g_examples/ch05_ddl/create_table.sql -- 查看执行结果(书中第5.4节的 DESC 命令验证) DESC employees;

@命令会自动识别当前路径下的.sql文件,并将其中每条语句按分号;分割执行。若脚本中含SPOOL命令(如ch13_backup/log_backup.sql),输出日志会自动写入同目录下的.lst文件,这是书中第13.5节备份验证的关键依据。

3. 脚本执行避坑指南:5个让初学者当场崩溃的真实错误与根治方案

这些坑我带过三届某高校数据库实训课,学生报错截图堆满钉钉群。它们不是“环境没配好”的模糊归因,而是有明确触发条件和可验证修复步骤的具体故障。

3.1 现象:执行@ch03_user/create_user.sql报 ORA-65096: invalid common user or role name

原因:你的 Oracle 11g 实例启用了 CDB(Container Database)模式,而书中脚本针对传统非CDB设计。CREATE USER c##test IDENTIFIED BY pwd中的c##前缀在 CDB 下才合法,但c##用户无法访问 PDB 中的表。
解决:

  1. 登录后执行SELECT NAME, CDB FROM V$DATABASE;,若CDB列返回YES,则需切换到 PDB:
    ALTER SESSION SET CONTAINER = ORCLPDB1; -- 替换为你的 PDB 名
  2. 修改脚本中的用户名,去掉c##前缀(如CREATE USER test IDENTIFIED BY pwd)
  3. 重新执行脚本

3.2 现象:@ch09_plsql/debug_pkg.pks编译成功,但@ch09_plsql/debug_pkg.pkb报 ORA-04063: package body "SYSTEM.DEBUG_PKG" has errors

原因:包体中引用了尚未创建的表(如debug_log表),而书中第9.3节要求先建表再编译包体,但脚本顺序未强制依赖。
解决:

  1. 先执行@D:/oracle11g_examples/ch09_plsql/create_debug_table.sql(该文件在配套包中存在但未被主脚本调用)
  2. 再执行包体编译命令
  3. 验证:SELECT object_name, status FROM user_objects WHERE object_type='PACKAGE BODY';应返回VALID

3.3 现象:@ch11_index/index_test_case.sql执行后EXPLAIN PLAN FOR SELECT * FROM t_index_test WHERE name='test';显示FULL TABLE SCAN,但书中图11-7明确标注走了INDEX RANGE SCAN

原因:测试表t_index_test数据量过小(< 20 行),Oracle 优化器认为全表扫描成本更低。书中第11.2节提到“需插入足够数据”,但未给出具体阈值。
解决:

  1. 修改脚本中INSERT INTO t_index_test循环次数,将i <= 1000改为i <= 5000
  2. 执行ANALYZE TABLE t_index_test COMPUTE STATISTICS;更新统计信息
  3. 再次执行EXPLAIN PLAN,PLAN_TABLE_OUTPUT中应出现INDEX RANGE SCAN IDX_T_NAME

3.4 现象:@ch12_sqltuning/sql_tuning_advisor_run.sql报 ORA-13780: SQL statement does not exist in the cursor cache

原因:SQL Tuning Advisor 需要分析已在共享池中执行过的语句,但脚本中SELECT /*+ FULL(t) */ * FROM employees t WHERE salary > 5000;是首次执行,未被缓存。
解决:

  1. 先手动执行一次目标 SQL(不加EXPLAIN PLAN):
    SELECT /*+ FULL(t) */ * FROM employees t WHERE salary > 5000;
  2. 再运行sql_tuning_advisor_run.sql,其中sql_id参数需替换为SELECT sql_id FROM v$sql WHERE sql_text LIKE '%FULL(t)%' AND ROWNUM=1;查询结果

3.5 现象:@ch13_backup/rman_full_backup.sql执行时报 RMAN-06171: not connected to target database

原因:RMAN 脚本需在 RMAN 命令行中执行,而非 SQL*Plus。书中第13.4节混淆了两种客户端。
解决:

  1. 退出 SQL*Plus,打开新终端
  2. 执行rman target /连接本地数据库
  3. 在 RMAN> 提示符下执行@D:/oracle11g_examples/ch13_backup/rman_full_backup.sql
  4. 注意:RMAN 脚本中ALLOCATE CHANNEL的DEVICE TYPE DISK FORMAT路径必须是数据库服务器上的绝对路径(如'/u01/backup/%U'),不能写 Windows 路径

4. 源码级调试实战:用书中 PL/SQL 包实现动态 SQL 执行与错误追踪

第9章的DEBUG_PKG不是摆设——它是把书中“如何定位存储过程错误”这一抽象概念,变成可触摸的调试武器。我们以ch09_plsql/transfer_money.prc(模拟转账存储过程)为例,演示如何用配套包的调试能力揪出隐藏 Bug。

4.1 构建可复现的错误场景

先执行书中第9.5节的转账脚本:

-- 创建测试账户(书中 ch03_user/create_user.sql 已建好 test 用户) CONNECT test/test@//192.168.56.101:1521/orcl11g @D:/oracle11g_examples/ch09_plsql/create_account_table.sql -- 插入初始数据 INSERT INTO accounts VALUES ('A', 1000); INSERT INTO accounts VALUES ('B', 500); COMMIT; -- 执行转账(故意传入不存在的账户名触发异常) EXEC transfer_money('A', 'C', 200); -- 账户 C 不存在,应抛出 NO_DATA_FOUND

此时屏幕只显示PL/SQL procedure successfully completed.,但账户余额没变——错误被静默吞掉了。这就是书中第9.5.2节强调的“异常处理陷阱”。

4.2 激活 DEBUG_PKG 的三层追踪机制

配套包的debug_pkg.pks/pkb提供了比DBMS_OUTPUT.PUT_LINE更强的追踪能力:

  • 第一层:DEBUG_PKG.START_TRACE记录进入点
  • 第二层:DEBUG_PKG.LOG_STEP记录关键变量值
  • 第三层:DEBUG_PKG.HANDLE_ERROR捕获并记录异常堆栈

修改transfer_money.prc,在EXCEPTION块中加入调试调用:

CREATE OR REPLACE PROCEDURE transfer_money( from_acct VARCHAR2, to_acct VARCHAR2, amount NUMBER ) AS from_bal NUMBER; to_bal NUMBER; BEGIN DEBUG_PKG.START_TRACE('TRANSFER_MONEY', 'from:'||from_acct||',to:'||to_acct||',amt:'||amount); SELECT balance INTO from_bal FROM accounts WHERE acct_id = from_acct; DEBUG_PKG.LOG_STEP('FROM_BALANCE', from_bal); SELECT balance INTO to_bal FROM accounts WHERE acct_id = to_acct; DEBUG_PKG.LOG_STEP('TO_BALANCE', to_bal); IF from_bal < amount THEN RAISE_APPLICATION_ERROR(-20001, 'Insufficient balance'); END IF; UPDATE accounts SET balance = balance - amount WHERE acct_id = from_acct; UPDATE accounts SET balance = balance + amount WHERE acct_id = to_acct; COMMIT; EXCEPTION WHEN NO_DATA_FOUND THEN DEBUG_PKG.HANDLE_ERROR('NO_DATA_FOUND for account '||SQLERRM); RAISE; WHEN OTHERS THEN DEBUG_PKG.HANDLE_ERROR('Unexpected error: '||SQLERRM||' at line '||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE); ROLLBACK; END; /

4.3 查看调试日志:从DEBUG_LOG表定位问题根源

执行EXEC transfer_money('A', 'C', 200);后,查询调试表:

SELECT log_time, step_name, log_value, error_msg FROM debug_log ORDER BY log_time DESC;

你会看到类似输出:

LOG_TIMESTEP_NAMELOG_VALUEERROR_MSG
2023-10-05 14:22:31NO_DATA_FOUND for account ORA-01403: no data foundNULLORA-01403: no data found
2023-10-05 14:22:31TO_BALANCENULLNULL

关键线索在LOG_VALUE为NULL的TO_BALANCE行——这证明SELECT ... INTO to_bal语句未赋值就跳转到了异常块。结合ERROR_MSG中的ORA-01403,瞬间定位到是to_acct = 'C'不存在导致的NO_DATA_FOUND。书中第9.5.3节说“异常处理要记录上下文”,这个DEBUG_LOG表就是最直接的上下文证据。

注意:DEBUG_LOG表默认每天自动清理(DELETE FROM debug_log WHERE log_time < SYSDATE-1),这是配套包debug_pkg.pkb中CLEANUP_LOG过程的默认行为。若需长期保留,执行EXEC DEBUG_PKG.SET_RETENTION_DAYS(7);。

5. 性能验证闭环:用 AWR 报告对比书中索引优化前后的执行计划差异

第12章讲 SQL 调优,但光看执行计划文字描述很难感知效果。配套包的awr_report_gen.sql脚本能把抽象的“逻辑读减少 40%”变成可视化的 AWR 报告对比,这才是工程师真正需要的验证闭环。

5.1 构造可度量的性能基线

先用书中第11章的index_test_case.sql创建测试环境:

-- 创建无索引的表(书中 ch11_index/no_index_test.sql) @D:/oracle11g_examples/ch11_index/no_index_test.sql -- 插入 10000 行测试数据(确保统计信息准确) INSERT INTO t_noindex_test SELECT ROWNUM, 'name'||ROWNUM, SYSDATE FROM DUAL CONNECT BY LEVEL <= 10000; COMMIT; EXEC DBMS_STATS.GATHER_TABLE_STATS('TEST', 'T_NOINDEX_TEST'); -- 记录基线 AWR 快照 ID(执行前) SELECT MAX(snap_id) FROM dba_hist_snapshot WHERE begin_interval_time > SYSDATE-1/24; -- 假设返回 12345

执行慢查询并生成基线报告:

-- 开启 SQL 跟踪(书中第12.3节) ALTER SESSION SET SQL_TRACE = TRUE; SELECT COUNT(*) FROM t_noindex_test WHERE name LIKE 'name%'; ALTER SESSION SET SQL_TRACE = FALSE; -- 生成 AWR 报告(使用配套脚本) @D:/oracle11g_examples/ch12_sqltuning/awr_report_gen.sql -- 脚本会提示输入:DBID(查 v$database)、实例号(1)、开始快照ID(12345)、结束快照ID(12346)

5.2 添加索引并生成对比报告

创建书中第11.4节推荐的函数索引:

CREATE INDEX idx_name_func ON t_noindex_test (UPPER(name)); EXEC DBMS_STATS.GATHER_TABLE_STATS('TEST', 'T_NOINDEX_TEST');

再次执行相同查询,生成新 AWR 报告:

-- 新快照 ID(假设为 12347) @D:/oracle11g_examples/ch12_sqltuning/awr_report_gen.sql -- 输入:开始快照ID(12346)、结束快照ID(12347)

5.3 对比报告中的三个黄金指标

打开生成的 HTML 报告(如awrrpt_1_12345_12346.html),重点看:

  1. SQL ordered by Elapsed Time:找到你的SELECT COUNT(*) FROM t_noindex_test...语句,对比两份报告中的Elapsed Time (s)。优化后应下降 60%+(从 2.3s → 0.8s)
  2. SQL ordered by Gets:Buffer Gets值应从数万降至数百,证明索引大幅减少了逻辑读
  3. Instance Activity Stats:physical reads和db block changes的差值,反映索引维护的额外开销(书中第11.5节警告的“写放大”)

血泪经验:AWR 报告默认只保留 8 天(DBA_HIST_SNAPSHOT),若你生成报告时提示no snapshots found,执行SELECT retention FROM dba_hist_wr_control;查看当前保留策略,必要时用EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(retention=>10080);(单位分钟)延长至 7 天。

从那以后我每次做 SQL 调优,都强制走一遍“建基线快照 → 执行 SQL → 建索引 → 新快照 → AWR 对比”四步闭环。不是为了交差,而是因为只有看到Buffer Gets从 15230 降到 127,我才敢在生产库上提交那个CREATE INDEX语句。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进