如何在Oracle中实时监控普通用户执行的DDL操作

夜宇大大_6142

夜宇大大_6142

2026-10-08

673人浏览

原创

必须用after ddl系统触发器,且由dba在目标用户schema或数据库级创建;普通用户无权创建,因其ddl操作不触发表级触发器,仅系统事件触发器可捕获create/drop/alter等动作。

如何在oracle中实时监控普通用户执行的ddl操作

直接上结论:必须用 AFTER DDL 系统触发器,且需在目标用户 schema 或数据库级创建;普通用户自身无法创建或启用该类触发器,权限必须由 DBA 授予。

为什么不能用普通用户自己建的触发器监控 DDL

DDL(如 CREATE TABLE、DROP INDEX)不是针对某张表的 DML 操作,它不走表级触发器路径。普通用户即使在自己 schema 下建了 BEFORE/AFTER INSERT OR UPDATE 触发器,对 ALTER USER 或 GRANT SELECT 这类 DDL 完全无感知——这些语句根本不会触发表级触发器。

真正能捕获 DDL 的只有 Oracle 的系统事件触发器,而这类触发器:

  • 必须由具有 ADMINISTER DATABASE TRIGGER 权限(通常是 SYS 或授权过的 DBA)创建
  • 作用域只能是 ON DATABASE(全库)或 ON SCHEMA(单 schema),不能绑定到普通用户会话里
  • 触发时机固定为 AFTER CREATE、AFTER DROP、AFTER ALTER 等,不支持 BEFORE(DDL 不可回滚)

如何创建有效监控的 DDL 触发器(DBA 操作)

假设你要监控用户 C##APPUSER 的所有 DDL 行为,推荐用 schema 级触发器,比数据库级更轻量、更聚焦:

第一步:确保审计表已存在(字段必须覆盖关键上下文)

QuantOracle
QuantOracle

63个确定性量化金融计算器 + 10个通过MCP的复合工作流。期权定价、Greeks、奇异衍生品、风险指标、投资组合优化……

下载
CREATE TABLE ddl_audit_log (
  id          NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  op_time     TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP,
  db_user     VARCHAR2(128),
  os_user     VARCHAR2(128),
  machine     VARCHAR2(64),
  ip_address  VARCHAR2(39),
  operation   VARCHAR2(30),
  object_type VARCHAR2(30),
  object_name VARCHAR2(128),
  sql_text    CLOB
);

第二步:DBA 执行触发器创建(注意替换 schema 名)

CREATE OR REPLACE TRIGGER tr_ddl_audit_cappuser
  AFTER CREATE OR DROP OR ALTER ON C##APPUSER.SCHEMA
DECLARE
  l_sql_text CLOB;
BEGIN
  -- 只捕获该 schema 下的 DDL,避免误录其他用户操作
  IF ORA_DICT_OBJ_OWNER = 'C##APPUSER' THEN
    -- 获取完整 SQL(需开启 EVENTS 10046 或依赖 ORA_SQL_TXT,但后者有长度限制)
    BEGIN
      SELECT sql_text INTO l_sql_text
        FROM v$sql
       WHERE sql_id = (SELECT prev_sql_id FROM v$session WHERE sid = SYS_CONTEXT('USERENV','SID'))
         AND ROWNUM = 1;
    EXCEPTION WHEN NO_DATA_FOUND THEN l_sql_text := '[SQL not found in shared pool]';
    END;
<pre class="brush:php;toolbar:false;">INSERT INTO ddl_audit_log (
  db_user, os_user, machine, ip_address,
  operation, object_type, object_name, sql_text
) VALUES (
  SYS_CONTEXT('USERENV', 'CURRENT_USER'),
  SYS_CONTEXT('USERENV', 'OS_USER'),
  SYS_CONTEXT('USERENV', 'HOST'),
  SYS_CONTEXT('USERENV', 'IP_ADDRESS'),
  ORA_SYSEVENT,
  ORA_DICT_OBJ_TYPE,
  ORA_DICT_OBJ_NAME,
  l_sql_text
);

END IF; END;

关键点:

  • ORA_SYSEVENT 给出真实动作('CREATE'、'DROP'),不是靠判断语句文本
  • ORA_DICT_OBJ_OWNER 必须显式校验,否则 ON SCHEMA 触发器在跨 schema 操作时也会触发(比如 C##APPUSER 执行 CREATE SYNONYM FOR HR.EMP)
  • v$sql 查 prev_sql_id 是取当前会话上一条执行的 SQL,比 ORA_SQL_TXT() 更可靠(后者最大只返回 1000 字符,且在某些版本中不可用)

常见错误现象和坑

你可能看到日志为空、只录了部分操作、或触发器报错 ORA-00604: error occurred at recursive SQL level 1,大概率是以下原因:

  • 没给触发器所在用户(如 SYS)对 ddl_audit_log 表的 INSERT 权限:GRANT INSERT ON ddl_audit_log TO SYS;
  • 触发器里用了未授权的视图(如 v$session):必须显式 GRANT SELECT ON v_$session TO your_trigger_owner;(注意是 v_$session,不是 v$session)
  • 试图在触发器里做复杂逻辑(如发邮件、调用外部 HTTP):DDL 触发器执行期间禁止提交/回滚,也不建议做耗时操作,否则会阻塞用户 DDL
  • 误用 ON DATABASE 却没加 owner 判断:结果把 DBA 自己建表、ANALYZE 等全记进去了,日志爆炸

真正难的不是写触发器,而是让 sql_text 字段稳定拿到完整语句——Oracle 并不保证 DDL 的原始文本一定留在 v$sql 里,尤其短命 SQL 或被老化淘汰后。如果审计要求 100% 精确,得搭配 ENABLE DDL LOGGING(12c+)或 AWR 快照补位,不能只靠一个触发器兜底。

相关专题

更多
oracle清空表数据
oracle清空表数据

当表中的数据不需要时,则应该删除该数据并释放所占用的空间。本专题为大家提供oracle清空表数据的相关文章,帮助大家解决该问题。

2023.08.16

901

5

Oracle中declare的使用
Oracle中declare的使用

Oracle DECLARE语句是PL/SQL编程语言中用于声明变量、常量、游标或异常的关键字。它的主要作用是在程序中定义这些对象,以便在后续的代码中使用。DECLARE语句的语法简单明了,可以根据需要声明多个对象。通过使用这些声明的对象,可以进行各种操作,如计算、查询数据库、处理异常等 。

2023.09.15

2573

5

oracle怎么分页
oracle怎么分页

实现分页的步骤:1、使用ROWNUM进行分页查询;2、在执行查询之前进行设置分页参数;3、使用"COUNT(*)"函数来获取总行数,并使用"CEIL"函数来向上取整计算总页数;4、在外部查询中使用"WHERE"子句来筛选出特定的行号范围,以实现分页查询。想了解更多oracle怎么分页的文章,可以来阅读本专题先的文章。

2023.09.18

2610

5

Oracle查看表操作历史记录
Oracle查看表操作历史记录

查看操作历史记录的方法:1、使用Oracle内置的审计功能,可以记录数据库中发生的各种操作,包括登录、DDL语句、DML语句等;2、使用Oracle日志文件,其中包含了数据库中发生的各种操作,可以通过查看日志文件来获取操作历史记录;3、使用Oracle的Flashback功能,可以查看数据库在某个时间点的操作历史记录;4、使用第三方工具等。本专题还提供其他查看表操作的文章,大家可以免费阅读。

2023.09.19

1489

3

Oracle中RAC的用法
Oracle中RAC的用法

Oracle中RAC的用法:1、通过在多个服务器上运行数据库实例来提供高可用性;2、允许在需要时增加或减少节点数量;3、通过将工作负载分布到多个节点上来实现负载均衡;4、使用共享存储来实现多个节点之间的数据共享;5、允许多个节点同时处理数据库请求,从而实现并行处理;6、提供了透明故障切换功能;7、使用了一些技术来确保数据的一致性;8、提供了管理工具来简化RAC环境的管理和维护。本专题还提供RAC相关的其他文章,大家可以免费阅读。

2023.09.19

2113

7

oracle imp
oracle imp

imp是Oracle数据库中的一个命令行工具,用于将导出的数据和对象从一个数据库实例导入到另一个数据库实例。imp命令的一般语法为“imp username/password@connect_string file=file_name [options]”。

2023.09.19

2769

4

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4329

19

oracle通配符有哪些
oracle通配符有哪些

oracle通配符有“%”、“_”、“[]”和“[^]"。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.08

237

5

oracle四舍五入怎么操作
oracle四舍五入怎么操作

oracle四舍五入操作可以使用ROUND函数来实现,其语法为“ROUND(number, decimal_places)”,其中,number是要进行四舍五入的数值,decimal_places是指定的小数位数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.14

706

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程