Oracle 常用脚本之查看数据表、字段、约束、索引等信息
作者: 不剪发的Tony老师
毕业于北京航空航天大学,十多年数据库管理与开发经验,目前在一家全球性的金融公司从事数据库架构设计。CSDN学院签约讲师以及GitChat专栏作者。csdn上的博客收藏于以下地址:https://tonydong.blog.csdn.net
文章目录
数据表
列出数据库中的表
列出指定用户的表
通过表名查找特定的表
查看表的创建/修改时间
字段
查看指定表中的字段
查看指定表中的虚拟/隐藏字段
查找包含指定字段的表
约束
查找指定表上的主键约束
查找主键约束对应的字段
查找缺少主键约束的表
查找指定表上的唯一约束
查找指定表上的外键约束
查找外键约束中涉及的表和字段
检查约束
非空约束
默认值
索引
查找指定表上的索引
查找索引对应的字段
模式比较
比较两个模式中的表和字段
比较两个表中的数据差异
大家好,我是只谈技术不剪发的 Tony 老师。前文介绍了如何查看 Oracle 中的用户、权限、用户资源配置等信息,今天我们来继续讨论如何通过 Oracle 数据字典查看数据库中的表、字段、约束、索引等信息。
数据表
列出数据库中的表
系统视图 dba_tables 中包含了数据库中所有的关系表信息,需要 DBA 权限才能查看:
select owner, table_name, tablespace_name, status, num_rows, avg_row_len
from dba_tables
where owner in ( -- 非系统模式用户
select username
from dba_users
where oracle_maintained = 'N');
其中,
OWNER 是表的拥有者;
TABLE_NAME 是表名;
TABLESPACE_NAME 是表所在的表空间;
STATUS 是表的状态,VALID 或者 UNUSABLE;
NUM_ROWS 是表中的数据行数,通过表的统计分析获得,可能不准确;
AVG_ROW_LEN 是数据行的平均长度,单位为字节。
📝关于视图 dba_tables 更多字段的说明可以参考官方文档。
另外,我们也可以通过 all_tables 视图查看当前用户可以访问所有表,或者使用 user_tables 视图查看当前用户拥有的所有表。
列出指定用户的表
通过以下语句可以查询指定用户拥有的表:
select owner, table_name, tablespace_name, status, num_rows, avg_row_len
from dba_tables
where owner = :user_name; -- 用户名
如果想要查看当前登录用户拥有的表,也可以直接查询 user_tables 视图:
select table_name, tablespace_name, status, num_rows, avg_row_len
from user_tables;
注意,user_tables 视图没有 OWNER 字段。
通过表名查找特定的表
以下语句可以用于查找名字中包含字符串“EMP”的所有表:
select owner, table_name, tablespace_name, status, num_rows, avg_row_len
from dba_tables
where table_name like '%EMP%';
使用 not like 运算符可以执行相反查找,使用 regexp_like 可以执行正则表达式查找。
查看表的创建/修改时间
系统视图 dba_objects、all_objects 以及 user_objects 中包含了各种对象(表、索引、视图、触发器、程序包等)的信息,可以用于查询对象的创建时间和最后一次修改时间。例如:
select t.owner, t.table_name, o.created, o.last_ddl_time
from dba_tables t
join dba_objects o on (o.owner = t.owner and o.object_name = t.table_name)
where t.owner = :user_name -- 用户名
and t.table_name = :table_name; -- 表名
字段
查看指定表中的字段
系统视图 dba_tab_columns、all_tab_columns 以及 user_tab_columns 包含了表、视图以及聚簇表中的字段信息。我们可以使用以下语句查看指定表中的字段:
select owner, table_name, column_name, column_id, data_type,
data_length, data_precision, data_scale, nullable, data_default
from dba_tab_columns
where owner = :user_name -- 用户名
and table_name = :table_name; -- 表名
其中,
OWNER 是表、视图、聚簇表的拥有者;
TABLE_NAME 是表、视图、聚簇表的名字;
COLUMN_NAME 是字段名;
COLUMN_ID 是字段的编号;
DATA_TYPE 是字段的数据类型,包括 NUMBER、CHAR、VARCHAR2、DATE、TIMESTAMP 等;
DATA_LENGTH 是字段的长度,单位为字节;
DATA_PRECISION 是 NUMBER 数据类型的精度或 FLOAT 类型的二进制精度;
DATA_SCALE 是数字类型的小数点位数;
NULLABLE 表示字段是否可空。
查看指定表中的虚拟/隐藏字段
Oracle 11g 增加了虚拟列(Virtual Column)的支持,Oracle 12c 增加了隐藏列(Invisible Column)的支持。这些字段的信息需要通过名字更短的视图 dba_tab_cols、all_tab_cols 以及 user_tab_cols 进行查看。例如:
select owner, table_name, column_name, column_id, data_type,
data_length, data_precision, data_scale, nullable, data_default
from dba_tab_cols
where owner = :user_name -- 用户名
and table_name = :table_name -- 表名
and (virtual_column = 'Y' or hidden_column = 'Y');
对于虚拟列,data_default 字段是计算字段值的表达式。
查找包含指定字段的表
以下查询返回了包含指定字段的数据表:
select owner, table_name
from dba_tab_cols
where column_name = :column_name; -- 字段名
同样也可以通过 like 运算符进行模糊查找。
约束
查找指定表上的主键约束
视图 dba_constraints、all_constraints 以及 user_constraints 包含了关于表中约束的定义信息。
以下查询返回了指定表上的主键:
select owner, table_name, constraint_name, status, deferrable, deferred, validated, index_name, invalid
from dba_constraints
where owner = :user_name -- 用户名
and table_name = :table_name -- 表名
and constraint_type = 'P';
其中,
OWNER 是约束的拥有者;
TABLE_NAME 是主键所在的表名;
CONSTRAINT_NAME 是约束名;
STATUS 是约束的状态,ENABLED 或者 DISABLED;
DEFERRABLE 表示约束是否可以延迟验证,DEFERRABLE 或者 NOT DEFERRABLE;
DEFERRED 表示约束是延迟验证(DEFERRED)或者立即验证(IMMEDIATE);
VALIDATED 表示启用约束是是否对已有的数据进行验证,VALIDATED 或者 NOT VALIDATED;
INDEX_NAME 是主键或者唯一约束使用的索引;
INVALID 表示约束是否已经失效,INVALID 或者 NULL;
CONSTRAINT_TYPE 是约束类型,P 表示主键。
查找主键约束对应的字段
视图 dba_cons_columns、all_cons_columns 以及 user_cons_columns 包含了约束对应的字段信息。
以下查询返回了指定表上的主键和对应的字段信息:
select cc.owner, cc.table_name, cc.constraint_name,
listagg(cc.column_name,',') within group (order by cc.position) as columns
from dba_constraints c
join dba_cons_columns cc on (c.owner = cc.owner and c.constraint_name = cc.constraint_name)
where c.constraint_type = 'P'
and cc.owner = :user_name -- 用户名
and cc.table_name = :table_name -- 表名
group by cc.owner, cc.table_name, cc.constraint_name;
其中,listagg 函数将多字段约束中的字段名使用逗号分隔进行连接。
查找缺少主键约束的表
通常来说,每个表都应该有一个主键。以下查询可以找出指定模式下没有主键的表:
select t.owner, t.table_name
from dba_tables t
left join dba_constraints c on (t.owner = c.owner and t.table_name = c.table_name and c.constraint_type = 'P')
where t.owner = :user_name -- 用户名
and c.constraint_type is null;
查找指定表上的唯一约束
外键约束的类型为 U,以下查询返回了指定表上的主键:
select owner, table_name, constraint_name, status, deferrable, deferred, validated, index_name, invalid
from dba_constraints
where owner = :user_name -- 用户名
and table_name = :table_name -- 表名
and constraint_type = 'U';
和主键约束类似,可以使用以下查询返回唯一约束对应的字段:
select cc.owner, cc.table_name, cc.constraint_name,
listagg(cc.column_name,',') within group (order by cc.position) as columns
from dba_constraints c
join dba_cons_columns cc on (c.owner = cc.owner and c.constraint_name = cc.constraint_name)
where c.constraint_type = 'U'
and cc.owner = :user_name -- 用户名
and cc.table_name = :table_name -- 表名
group by cc.owner, cc.table_name, cc.constraint_name;
查找指定表上的外键约束
外键约束的类型为 R,以下查询返回了指定表上的外键:
select owner, table_name, constraint_name, r_owner, r_constraint_name, delete_rule,
status, deferrable, deferred, validated, invalid
from dba_constraints
where owner = :user_name -- 用户名
and table_name = :table_name -- 表名
and constraint_type = 'R';
其中,
R_OWNER 是外键约束被引用表的拥有者;
R_CONSTRAINT_NAME 是被引用表上对应的主键或者唯一约束;
DELETE_RULE 是外键约束的级联删除规则,CASCADE、SET NULL 或者 NO ACTION;
其他字段可以参考上文中的主键约束。
查找外键约束中涉及的表和字段
以下查询返回了指定表上的外键约束,包括引用字段和被引用表上的参照字段:
select c.owner, c.table_name, listagg(cc.column_name,',') within group (order by cc.position) columns, c.constraint_name,
c.r_owner, rc.table_name r_table_name, listagg(rcc.column_name,',') within group (order by rcc.position) r_columns, c.r_constraint_name
from dba_constraints c
join dba_cons_columns cc on (c.owner = cc.owner and c.constraint_name = cc.constraint_name)
join dba_constraints rc on (rc.constraint_name = c.r_constraint_name)
join dba_cons_columns rcc on (rc.owner = rcc.owner and rc.constraint_name = rcc.constraint_name)
where c.owner = :user_name -- 用户名
and c.table_name = :table_name -- 表名
and c.constraint_type = 'R'
group by c.owner, c.table_name, c.constraint_name, c.r_owner, rc.table_name, c.r_constraint_name;
检查约束
检查约束和非空约束的类型都是 C,以下查询返回了指定表上的检查约束和非空约束
select owner, table_name, constraint_name, search_condition_vc, delete_rule,
status, deferrable, deferred, validated, invalid
from dba_constraints
where owner = :user_name -- 用户名
and table_name = :table_name -- 表名
and constraint_type = 'C';
其中,
SEARCH_CONDITION_VC 是检查约束的验证条件;
其他字段可以参考上文中的主键约束。
和主键约束类似,可以使用以下查询返回检查约束对应的字段:
select c.owner, c.table_name, c.constraint_name, c.search_condition_vc,
listagg(cc.column_name,',') within group (order by cc.position) as columns
from dba_constraints c
join dba_cons_columns cc on (c.owner = cc.owner and c.constraint_name = cc.constraint_name)
where c.constraint_type = 'C'
and c.owner = :user_name -- 用户名
and c.table_name = :table_name -- 表名
group by c.owner, c.table_name, c.constraint_name, c.search_condition_vc;
非空约束
非空约束可以通过检查约束进行查看,参考上文。
另一种查看非空字段的方式是查询 dba_tab_columns 或者相关视图,例如:
select owner, table_name, column_name, column_id, data_type,
data_length, data_precision, data_scale, nullable, data_default
from dba_tab_columns
where owner = :user_name -- 用户名
and table_name = :table_name -- 表名
and nullable = 'N';
默认值
字段的默认值可以直接查询 dba_tab_columns 或者相关视图,例如:
select owner, table_name, column_name, column_id, data_type,
data_length, data_precision, data_scale, nullable, data_default
from dba_tab_columns
where owner = :user_name -- 用户名
and table_name = :table_name -- 表名
and data_default is not null;
索引
查找指定表上的索引
视图 dba_indexes、all_indexes 以及 user_indexes 包含了关于数据库中的索引信息。
以下查询返回了指定表上的索引:
select table_owner, table_name, table_type, owner, index_name, index_type, uniqueness, status, visibility
from dba_indexes
where table_owner = :user_name -- 用户名
and table_name = :table_name; -- 表名
其中,
TABLE_OWNER 是被索引对象的拥有者;
TABLE_NAME 被索引对象的名称;
TABLE_TYPE 是被索引对象的类型,包括 TABLE、VIEW、SYNONYM 等;
OWNER 是索引的拥有者;
INDEX_NAME 是索引的名称;
INDEX_TYPE 是索引的类型,包括 NORMAL、BITMAP、FUNCTION-BASED NORMAL 等;
UNIQUENESS 表示该索引是否具有唯一性,UNIQUE 或者 NONUNIQUE;
STATUS 是非分区索引的状态,VALID 或者 UNUSABLE;
VISIBILITY 是索引的可见性,VISIBLE 或者 INVISIBLE。
查找索引对应的字段
视图 dba_ind_columns、all_ind_columns 以及 user_ind_columns 包含了索引对应的字段信息。
select i.table_owner, i.table_name, i.index_name, i.index_type, i.uniqueness,
listagg(ic.column_name||' '|| ic.descend, ',') within group(order by ic.column_position) as columns
from dba_indexes i
join dba_ind_columns ic on (i.table_owner = ic.table_owner and i.index_name = ic.index_name)
where i.table_owner = :user_name -- 用户名
and i.table_name = :table_name -- 表名
group by i.table_owner, i.table_name, i.index_name, i.index_type, i.uniqueness;
其中,listagg 函数将复合索引中的字段名使用逗号分隔进行连接。
模式比较
比较两个模式中的表和字段
以下查询用于比较两个模式,返回任意模式中缺少的表和字段,以及数据类型或者字段长度不匹配的字段:
select coalesce(s1.table_name, s2.table_name) table_name,
coalesce(s1.column_name, s2.column_name) column_name,
s1.data_type data_type1, s1.data_length data_length1,
s2.data_type data_type2, s2.data_length data_length2
from (
select table_name,
column_name,
data_type,
data_length
from dba_tab_cols
where owner = :user_name1 -- 模式用户 1
) s1
full join (
select table_name,
column_name,
data_type,
data_length
from dba_tab_cols
where owner = :user_name2 -- 模式用户 2
) s2
on (s2.table_name = s1.table_name and s2.column_name = s1.column_name)
where s1.column_name is null
or s2.column_name is null
or s1.data_type != s2.data_type
or s1.data_length != s2.data_length
order by table_name, column_name;
比较两个表中的数据差异
以下语句可以用于比较两个结构相同的表中的数据差异:
(
select 'T1', col1, col2, ... from schema1.table1
minus
select 'T1', col1, col2, ... from schema2.table2
)
union all
(
select 'T2', col1, col2, ... from schema2.table2
minus
select 'T2', col1, col2, ... from schema1.table1
);
如果觉得文章对你有用,欢迎关注❤️、评论📝、点赞👍!