服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > 数据库技术 > Oracle技术 > Oracle开发 > 查看文档

进行logmnr操作时发现空列名的具体原因

在处理一些已经提交的数据时,因为提交的时间超过了可以闪回的时间,所以采用了logmnr来处理。在处理的过程中,很多人都会发现得到的sql语句中,包含了空列的情况。

例子:

sql> conn sys@ytk102 as sysdba输入口令: 已连接。
sql> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';

会话已更改。

sql> select group#, first_time from v$log;

group# first_time
---------- -------------------
1 2008-01-18 22:35:57
2 2008-01-20 18:58:37
3 2008-01-16 23:56:50

sql> select member from v$logfile where group# = 2;

member
-------------------------------
e:oracleoradataytk102redo02.log

sql> alter system switch logfile;

系统已更改。

sql> exec dbms_logmnr.add_logfile('e:oracleoradataytk102redo02.log', dbms_logmnr.new)

pl/sql 过程已成功完成。

sql> exec dbms_logmnr.start_logmnr(options => dbms_logmnr.dict_from_online_catalog)

pl/sql 过程已成功完成。

sql> select sql_undo from v$logmnr_contents
2 where seg_name = 't_logmnr';

sql_undo
--------------------------------------------------------------------------
insert into "yangtk"."t_logmnr"("id","name","") values ('1','a',null);
insert into "yangtk"."t_logmnr"("id","name","") values ('2','b',null);
insert into "yangtk"."t_logmnr"("id","name","") values ('3','c',null);

在此部分可以看到t_logmnr表后面跟了一个空的列,而这个列的值也是null。

检查表结构:

sql> desc yangtk.t_logmnr
名称 是否为空? 类型
------------------------- -------- ----------------
id not null number
name varchar2(30)

sql> select table_name, column_name from dba_tab_columns
2 where table_name = 't_logmnr'
3 and owner = 'yangtk';

table_name column_name
------------------------------ ---------------------
t_logmnr id
t_logmnr name

从数据字典中找不到这个空列的信息,直接查询col$表:

sql> select object_id from dba_objects
2 where object_name = 't_logmnr'
3 and owner = 'yangtk';

object_id
----------
53636

sql> select name from col$ where obj# = 53636;

name
------------------------------
id
name
sys_nc00003$

从col$中可以看到这个隐藏列了,检查隐藏列:

sql> select name, default$ from col$ where obj# = 53636;

name default$
------------------------------ -----------------------
id
name
sys_nc00003$ decode("id",1,"name"||'1',"name"||'2')

现在已经可以看出这个列是一个基于基础列的函数表达式,对比函数索引列:

sql> select index_name, index_type, uniqueness from dba_indexes
2 where table_name = 't_logmnr'
3 and table_owner = 'yangtk';

index_name index_type uniquenes
------------------- ---------------- ---------
sys_c005983 normal unique
ind_t_logmnr_name function-based normal nonunique

sql> select column_expression from dba_ind_expressions 
2 where table_name = 't_logmnr'
3 and table_owner = 'yangtk'
4 and index_name = 'ind_t_logmnr_name';

column_expression
------------------------------------------------
decode("id",1,"name"||'1',"name"||'2')

至此,我们可以看到,这个隐藏列就是函数索引产生的。

扫描关注微信公众号