Oracle SQL 查询列出所有活动用户/模式并给出对象计数

Posted

技术标签:

【中文标题】Oracle SQL 查询列出所有活动用户/模式并给出对象计数【英文标题】:Oracle SQL query to list all active users/schemas and give object count 【发布时间】:2016-11-15 23:53:06 【问题描述】:

我正在尝试编写一个查询,该查询将为我提供有关用户/模式的信息。

它需要使用以下内容:

COLUMNS = 用户名、default_tablespace、account_status 表 = dba_users

PLUS,结果集中的一个新虚拟列显示该用户名/模式的对象计数。即它拥有的对象的数量。 简单的 where 子句应该是 account_status 是打开的,并且用户名不是 X、Y、Z 之一。

所以它将以某种方式结合以下基本查询:

select username, default_tablespace, account_status
from dba_users
where account_status = 'OPEN'
and username not in ('GEORGE','ANNA','BOB')

有了这个:

select owner, count(*) as object_count from dba_objects
group by owner
order by 1

我尝试尝试使用行内查询。我能想到的最好的查询是下面的查询,但这仅列出了 dba_objects 表中存在的用户。即仅列出架构(包含至少 1 个对象)而不是普通用户。

select username, account_status, default_tablespace, subquery1.object_count 
from dba_users,
(
select owner,count(*) as object_count from dba_objects
group by owner order by 1
) subquery1
where username = owner
and account_status = 'OPEN'
and username not in ('GEORGE','ANNA','BOB')
order by username

我认为我需要执行左外连接,以保留满足其余查询的 dba_users 记录,因此在 object_count 列中仅返回“NULL”,但是当我尝试如下时,我得到垃圾结果,它列出了太多,重复用户多次随机对象计数。

select username, account_status, default_tablespace, subquery1.object_count 
from dba_users,
(
select owner, count(*) as object_count from dba_objects
group by owner order by 1
) subquery1
left join dba_users on username = subquery1.owner
and account_status = 'OPEN'
and username not in ('GEORGE','ANNA','BOB')
order by username

作为奖励,如果有人能提出一个不仅提供上述内容的查询,而且还提供一个额外的虚拟列,提供所用表空间的大小,那就太好了。所以它会使用类似下面的查询:

选择 round((sum(bytes)/1024/1024/1024),1) 作为 size_in_gb,所有者 来自 dba_segments 通过...分组 所有者

非常感谢。

【问题讨论】:

【参考方案1】:

有很多方法可以构建这样的查询。如果您只从另一个表中获取单个值,我会很想进行内联选择,而不是费心进行显式连接

select username, default_tablespace, account_status,
       (select count(1)
          from dba_objects o
         where o.owner = u.username) cnt_objects_owned,
       (select sum(bytes)
          from dba_segments s
         where s.owner = u.username) total_size_of_segments
  from dba_users u
 where account_status = 'OPEN'
   and username not in ('GEORGE','ANNA','BOB')

这样做的好处是添加新的内联选择相对容易。但是,如果将来您想从 dba_objectsdba_segments 获取多个值,并且最终在其他内联选择中重复自己,这将非常低效。

有趣的是,如果我将查询中的 count(1) 更改为 count(*),我会不断收到错误消息

【讨论】:

我似乎已经过分复杂化了,(像往常一样)尝试使用 from 子句中的内联查询,而不是初始选择。非常感谢,这实现了我所需要的一切。是的,它很慢……但是,嘿。谢谢。

以上是关于Oracle SQL 查询列出所有活动用户/模式并给出对象计数的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL:经典查询练手第一篇

怎样在ORACLE中查询并列出所有含某一列名(如NAME)的表;

我需要使用啥 SQL 来列出 Oracle 数据库上的所有存储过程?

怎么查询oracle中响应时间最长的sql语句,并列出平均响应时间

Oracle SQL 中结合 LIMIT 子句访问主表字段的子查询

如何在 oracle 中创建新模式并列出所有模式名称