我想从mssql服务器实例获取所有用户数据库的列表。最好的方法是什么?
我知道我可以从sys.databases中进行选择,但除了硬编码要排除的名称列表之外,我没有看到任何方法来过滤掉系统数据库。
我需要脚本在2000/2005和2008上工作。
如果我上面列出的方法是唯一的方法,那么我应该排除哪些名称?我不知道2005年或2008年是否添加了任何新的系统数据库。
答案 0 :(得分:10)
今天再次关注此事,并决定分析Management Studio正在做什么来填充对象资源管理器的详细信息。
原来微软已经实施的解决方案非常简单,归结为以下几点:
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';