如何通过查询DBA_OBJECTS表的CREATED字段来获取Oracle数据库中各段的创建时间?
- 内容介绍
- 文章标签
- 相关推荐
本文共计807个文字,预计阅读时间需要4分钟。
相关专题:
oracle 中段(segment)的创建时间,本质上就是其对应数据库对象(如表、索引、lob等)的创建时间,直接查 dba_objects 的 created 字段即可——但必须注意:这不是段物理分配时间,而是对象首次 ddl 成功执行的时间,且该字段不会随 truncate、move 或高水位调整而更新。
为什么不能直接查 DBA_SEGMENTS 的 CREATED 字段
DBA_SEGMENTS 视图里根本没有 CREATED 列。它只提供段的物理属性(如 BYTES、EXTENTS、SEGMENT_NAME、SEGMENT_TYPE),不记录元数据时间戳。试图 SELECT CREATED FROM DBA_SEGMENTS 会报 ORA-00904: "CREATED": invalid identifier 错误。
DBA_OBJECTS.CREATED 是最可靠来源
只要对象属于段类型(SEGMENT_TYPE IN ('TABLE', 'INDEX', 'LOBSEGMENT', 'LOBINDEX', 'TABLE PARTITION', 'INDEX PARTITION' 等),它的 CREATED 值就代表该段首次被创建的时间点。使用时需注意:
-
DBA_OBJECTS要求SELECT_CATALOG_ROLE或DBA权限,普通开发用户通常无权访问 -
OBJECT_NAME和OWNER都是大写存储,建议显式用UPPER()或全大写匹配,避免大小写问题 -
CREATED是DATE类型,精度到秒,不包含毫秒或时区信息 - 如果对象被
DROP后重建,CREATED会变成新时间;但如果是ALTER ... MOVE或REBUILD,CREATED不变,只有LAST_DDL_TIME更新
关联 DBA_SEGMENTS 获取段级物理信息
要同时拿到段大小和创建时间,得把 DBA_SEGMENTS 和 DBA_OBJECTS 关联查询。关键匹配字段是 OWNER + SEGMENT_NAME = OWNER + OBJECT_NAME,且限定 OBJECT_TYPE 与 SEGMENT_TYPE 语义一致:
SELECT s.OWNER, s.SEGMENT_NAME, s.SEGMENT_TYPE, s.BYTES / 1024 / 1024 AS MB, o.CREATED FROM DBA_SEGMENTS s JOIN DBA_OBJECTS o ON s.OWNER = o.OWNER AND s.SEGMENT_NAME = o.OBJECT_NAME AND s.SEGMENT_TYPE = o.OBJECT_TYPE WHERE s.OWNER = 'SCOTT' AND s.SEGMENT_TYPE IN ('TABLE', 'INDEX', 'LOBSEGMENT');
注意:DBA_SEGMENTS 中可能有同名但不同类型的段(比如表和它的 LOB 段),所以必须用 SEGMENT_TYPE = OBJECT_TYPE 过滤,否则会多出重复或错配行。
容易忽略的权限与空值陷阱
即使你有 DBA 角色,某些对象(如全局临时表、物化视图日志)在 DBA_OBJECTS 中的 CREATED 可能为 NULL;另外,分区对象的子分区不会单独出现在 DBA_OBJECTS,只显示一级分区或模板定义。真正难搞的是:如果表建在本地管理的表空间中且启用了延迟段创建(DEFERRED_SEGMENT_CREATION=TRUE),那么刚 CREATE TABLE 后,DBA_SEGMENTS 里还没记录,但 DBA_OBJECTS 里已有 CREATED ——这时“段创建时间”实际晚于对象创建时间,直到第一次 INSERT 或手动 ALLOCATE EXTENT 才真正落地。
本文共计807个文字,预计阅读时间需要4分钟。
相关专题:
oracle 中段(segment)的创建时间,本质上就是其对应数据库对象(如表、索引、lob等)的创建时间,直接查 dba_objects 的 created 字段即可——但必须注意:这不是段物理分配时间,而是对象首次 ddl 成功执行的时间,且该字段不会随 truncate、move 或高水位调整而更新。
为什么不能直接查 DBA_SEGMENTS 的 CREATED 字段
DBA_SEGMENTS 视图里根本没有 CREATED 列。它只提供段的物理属性(如 BYTES、EXTENTS、SEGMENT_NAME、SEGMENT_TYPE),不记录元数据时间戳。试图 SELECT CREATED FROM DBA_SEGMENTS 会报 ORA-00904: "CREATED": invalid identifier 错误。
DBA_OBJECTS.CREATED 是最可靠来源
只要对象属于段类型(SEGMENT_TYPE IN ('TABLE', 'INDEX', 'LOBSEGMENT', 'LOBINDEX', 'TABLE PARTITION', 'INDEX PARTITION' 等),它的 CREATED 值就代表该段首次被创建的时间点。使用时需注意:
-
DBA_OBJECTS要求SELECT_CATALOG_ROLE或DBA权限,普通开发用户通常无权访问 -
OBJECT_NAME和OWNER都是大写存储,建议显式用UPPER()或全大写匹配,避免大小写问题 -
CREATED是DATE类型,精度到秒,不包含毫秒或时区信息 - 如果对象被
DROP后重建,CREATED会变成新时间;但如果是ALTER ... MOVE或REBUILD,CREATED不变,只有LAST_DDL_TIME更新
关联 DBA_SEGMENTS 获取段级物理信息
要同时拿到段大小和创建时间,得把 DBA_SEGMENTS 和 DBA_OBJECTS 关联查询。关键匹配字段是 OWNER + SEGMENT_NAME = OWNER + OBJECT_NAME,且限定 OBJECT_TYPE 与 SEGMENT_TYPE 语义一致:
SELECT s.OWNER, s.SEGMENT_NAME, s.SEGMENT_TYPE, s.BYTES / 1024 / 1024 AS MB, o.CREATED FROM DBA_SEGMENTS s JOIN DBA_OBJECTS o ON s.OWNER = o.OWNER AND s.SEGMENT_NAME = o.OBJECT_NAME AND s.SEGMENT_TYPE = o.OBJECT_TYPE WHERE s.OWNER = 'SCOTT' AND s.SEGMENT_TYPE IN ('TABLE', 'INDEX', 'LOBSEGMENT');
注意:DBA_SEGMENTS 中可能有同名但不同类型的段(比如表和它的 LOB 段),所以必须用 SEGMENT_TYPE = OBJECT_TYPE 过滤,否则会多出重复或错配行。
容易忽略的权限与空值陷阱
即使你有 DBA 角色,某些对象(如全局临时表、物化视图日志)在 DBA_OBJECTS 中的 CREATED 可能为 NULL;另外,分区对象的子分区不会单独出现在 DBA_OBJECTS,只显示一级分区或模板定义。真正难搞的是:如果表建在本地管理的表空间中且启用了延迟段创建(DEFERRED_SEGMENT_CREATION=TRUE),那么刚 CREATE TABLE 后,DBA_SEGMENTS 里还没记录,但 DBA_OBJECTS 里已有 CREATED ——这时“段创建时间”实际晚于对象创建时间,直到第一次 INSERT 或手动 ALLOCATE EXTENT 才真正落地。

