如何通过t-sql获取所有用户数据库的列表?

时间:2009-01-20 21:06:42

标签: sql-server

我想从mssql服务器实例获取所有用户数据库的列表。最好的方法是什么?

我知道我可以从sys.databases中进行选择,但除了硬编码要排除的名称列表之外,我没有看到任何方法来过滤掉系统数据库。

我需要脚本在2000/2005和2008上工作。

如果我上面列出的方法是唯一的方法,那么我应该排除哪些名称?我不知道2005年或2008年是否添加了任何新的系统数据库。

8 个答案:

答案 0 :(得分:10)

今天再次关注此事,并决定分析Management Studio正在做什么来填充对象资源管理器的详细信息。

Object Explorer > System Databases

原来微软已经实施的解决方案非常简单,归结为以下几点:

SELECT *
FROM   master.sys.databases
WHERE  Cast(CASE WHEN name IN ('master', 'model', 'msdb', 'tempdb') THEN 1 ELSE is_distributor END As bit) = 0

请注意,这是使用 SSMS 2008R2 (10.50.4033.0)执行的。

答案 1 :(得分:8)

第一个查询将返回一个表,其中包含有关实例上所有数据库的数据:

Select * 
From sys.databases

从此表中您会注意到,您可以使用WHERE子句缩小所需数据的范围。例如,以下查询将返回相同的结果表(您最有可能寻找的那个):

Select * 
From sys.databases 
Where database_id > 5


Select * 
From sys.databases 
Where len(owner_sid)>1

这些查询将在SQL Server 2008和2012中有效。

答案 2 :(得分:5)

在SQL Server 2008 R2 Express上,看起来我无法可靠地使用上述任何方法。 INFORMATION_SCHEMA.SCHEMATA只显示当前数据库中的信息,db_id(database_id)#5是我的第一个用户数据库,我的一个镜像数据库(在SQL Server 2008 R2 Standard上运行)上的两个用户数据库上的owner_sid显示owner_sid = 1为我最近创建的两个数据库。 (PablolnNZ上面的评论是正确的:我没有为这两个数据库设置明确的所有者,因此它仍然显示为拥有' sa的所有者。)

我能够使用的唯一可靠方法如下:

SELECT name FROM sys.databases
WHERE name NOT IN ('master', 'model', 'tempdb', 'msdb', 'Resource')

答案 3 :(得分:4)

这适用于2005年,不是100%肯定其他版本,但我认为它会飞。这有点像黑客但可能会得到你所需要的东西:

 select * from sys.databases where len(owner_sid)>1

答案 4 :(得分:3)

听起来很讨厌硬编码。对于多个SQL版本,系统数据库的名称和数量相当一致。但是,如果这太令人不愉快,您可以将它们半硬编码到表中,然后将其插入查询中。

答案 5 :(得分:0)

不确定你是否可以随便。一个注意事项 - 在2k上你必须使用master.dbo.sysdatabases而不是master.sys.databases(在2k中不存在)。

答案 6 :(得分:0)

这适用于2000年至2008年R2

SELECT name
FROM dbo.sysdatabases 
WHERE dbid > 5

答案 7 :(得分:0)

从SQL Server 2008开始,您可以访问名为sys.databases的视图,当与sys.server_principals结合使用时,可以删除 sa 所拥有的数据库,您可以(最常见的) )安全地辨别“系统数据库”。因此,允许您过滤这些项目。

select
  d.name
  ,d.database_id
from
  sys.databases d
join
  sys.server_principals p
  on p.sid = d.owner_sid
where
  p.name <> 'sa';