我正在为我们的数据库中的变化实现依赖系统,例如,对于这个和这个变化,我们需要那个和那个处于这样那样状态的对象。使用 DDL 依赖关系很容易,但我需要知道给定的 DML 子句引用了哪些对象。后者也可以是动态的。
所以问题是:有没有办法说,给定的 DML 代码引用了哪些表?
主要我对那些不会立即在我的数据集上修改表但可能应该在客户端修改它的子句感兴趣,因为我不可能拥有所有的变化。因此,间接的理解方式(例如执行 DML,然后检查哪些表已更改)不是一种选择。
我正在为我们的数据库中的变化实现依赖系统,例如,对于这个和这个变化,我们需要那个和那个处于这样那样状态的对象。使用 DDL 依赖关系很容易,但我需要知道给定的 DML 子句引用了哪些对象。后者也可以是动态的。
所以问题是:有没有办法说,给定的 DML 代码引用了哪些表?
主要我对那些不会立即在我的数据集上修改表但可能应该在客户端修改它的子句感兴趣,因为我不可能拥有所有的变化。因此,间接的理解方式(例如执行 DML,然后检查哪些表已更改)不是一种选择。
如果 DML 代码是查询,您可以对其进行解释,然后检查PLAN_TABLE
或dbms_xplan.display_cursor
检查查询引用了哪些对象。
SQL> delete from plan_table;
4 rows deleted
SQL> explain plan for select * from scott.emp;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2872589290
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 518 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| EMP | 14 | 518 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------
8 rows selected
SQL> SELECT operation, object_owner, object_name FROM plan_table;
OPERATION OBJECT_OWNER OBJECT_NAME
-------------------- ------------------ --------------------
SELECT STATEMENT
TABLE ACCESS SCOTT EMP
显然,这需要查询在数据库中有效(所有引用的对象都已经存在,等等......)。如果要分析的代码是一个 PL/SQL 块,我看不出你怎么能不写一个 DIY 解析器。
我进一步调查并发现:
数据库更改通知在不修改当前数据状态的任何子句上不起作用(惊喜!)。
但我想我最终会使用 AUDIT/FGA。到目前为止,它似乎可以理解子句,这些子句并没有真正改变任何东西,可以很好地与 PL/SQL 块中的显式和动态 DML 配合使用,并提供 object_name - 这正是我所需要的。