ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 函数索引产生隐藏列

函数索引产生隐藏列

Linux操作系统 作者:yangtingkun 时间:2008-01-20 23:45:21 0 删除 编辑

前两天在进行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:\ORACLE\ORADATA\YTK102\REDO02.LOG

SQL> ALTER SYSTEM SWITCH LOGFILE;

系统已更改。

SQL> EXEC DBMS_LOGMNR.ADD_LOGFILE('E:\ORACLE\ORADATA\YTK102\REDO02.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 WNER = '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 WNER = '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')

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

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-3132486/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1964
  • 访问量
    11073955