如何在SQL Server中检查数据库是否存在?

326

如何使用TSQL检查SQL Server上的数据库是否存在?似乎有多种方法可以实现。

7个回答

606

5
它确实更短并且更加简洁。出于好奇,为什么它更好呢? - Mike K
8
可能是因为使用db_id比在[master]特定位置检查数据库名称更安全。 - Anthony
4
是的,而且db_id()几乎不可能比被接受的答案更差(可能具有相同的复杂度/成本),因为db_id查询一个数字。因此,我更愿意打赌db_id()是以更聪明的方式实现的,因为它是由数据库开发人员完成的。 - Eduardo
3
如果您遇到权限问题,比如您没有权限访问[master],那么这个方法很有效! - Jason Foglia
3
@MadTigger:在调用db_id时,不应该包含[ ];那是SQL语法,而不是数据库名称的一部分。 - Jacob Krall
显示剩余8条评论

179

从微软的脚本中:

DECLARE @dbname nvarchar(128)
SET @dbname = N'Senna'

IF (EXISTS (SELECT name 
FROM master.dbo.databases 
WHERE ('[' + name + ']' = @dbname 
OR name = @dbname)))

7
这可能是来自微软脚本,但这不是微软推荐的做法。他们鼓励使用INFORMATION_SCHEMA视图而不是直接访问系统表。 - mwigdahl
4
为什么鼓励使用INFORMATION_SCHEMA而不是直接使用表的引用? - eKek0
5
一般来说,这是因为微软承诺使用INFORMATION_SCHEMA格式,并保留更改系统表的权利。但是在这种情况下,经过仔细查看,发现INFORMATION_SCHEMA无法使用,所以这可能是最佳选择。 - mwigdahl
3
我同意使用INFORMATION_SCHEMA来检查数据库中的对象。但是,INFORMATION_SCHEMA能否用于检查数据库本身?以下是需要翻译的内容:CHECK_CONSTRAINTS 约束条件、COLUMN_DOMAIN_USAGE 具有用户定义数据类型的每个列、COLUMN_PRIVILEGES 当前数据库中授予或由当前用户授予的每个列的权限、COLUMNS 系统中每个列都会被列出、CONSTRAINT_COLUMN_USAGE 在其上定义了约束条件的每个列、CONSTRAINT_TABLE_USAGE 定义了约束条件的每个表。 - granadaCoder
4
@mwigdahl - 请提供这个所声称的推荐做法的参考文献。 - Martin Smith
显示剩余7条评论

50
IF EXISTS (SELECT name FROM master.sys.databases WHERE name = N'YourDatabaseName')
  Do your thing...

顺便说一下,这是直接从SQL Server Studio获取的,如果你可以访问这个工具,我建议你开始尝试使用各种可用的“Script xxxx AS”函数。会让你的生活更轻松! :)


4
如果“USE [Master]”不方便,您可以直接从任何数据库中使用“master.sys.databases”来访问视图。 - ProfK

10

我喜欢@Eduardo的回答,也喜欢被采纳的回答。我想从这样的东西中得到一个布尔值,所以我为你们写了这个。

CREATE FUNCTION dbo.DatabaseExists(@dbname nvarchar(128))
RETURNS bit
AS
BEGIN
    declare @result bit = 0 
    SELECT @result = CAST(
        CASE WHEN db_id(@dbname) is not null THEN 1 
        ELSE 0 
        END 
    AS BIT)
    return @result
END
GO

现在你可以像这样使用它:

select [dbo].[DatabaseExists]('master') --returns 1
select [dbo].[DatabaseExists]('slave') --returns 0

5

试一试

IF EXISTS 
   (
     SELECT name FROM master.dbo.sysdatabases 
    WHERE name = N'New_Database'
    )
BEGIN
    SELECT 'Database Name already Exist' AS Message
END
ELSE
BEGIN
    CREATE DATABASE [New_Database]
    SELECT 'New Database is Created'
END

0
如果其他方法都不起作用,试试这个。这是微软推荐的
USE tempdb;
GO
DECLARE @SQL nvarchar(1000);
IF EXISTS (SELECT 1 FROM sys.databases WHERE [name] = N'Sales')
BEGIN
    SET @SQL = N'USE [Sales];
    ALTER DATABASE Sales SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    USE [tempdb];

    DROP DATABASE Sales;';
    EXEC (@SQL);
END;

将代码中的销售部分更改为您想要删除的数据库的名称。

我所说的“推荐”是指它在文档中有提及。请在此页面上查看:https://learn.microsoft.com/zh-cn/sql/t-sql/statements/drop-database-transact-sql?view=sql-server-ver16 - undefined
太棒了。当有可用的参考时,请在您的回答中包含这样的参考。说微软推荐是一回事,而展示微软推荐又是另一回事。 - undefined
@Chris 下次我们会记住的。 - undefined

-1
  Public Function SQLDatabaseExist(ByVal DefaultConnectionString As String, ByVal DataBaseName As String) As Boolean
Try
    'CREATE DATABASE
    Dim SqlString As String = ""
    SqlString = "SELECT CASE WHEN EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = N'" & DataBaseName & "') THEN CAST (1 AS BIT) ELSE CAST (0 AS BIT) END"
    Dim ExcRet As Integer = 0
    Using connection As New SqlConnection(DefaultConnectionString)
        Dim command As New SqlCommand(SqlString, connection)
        command.Connection.Open()
        ExcRet = command.ExecuteScalar()
        command.Connection.Close()
        command.Dispose()
    End Using
    Return ExcRet
Catch ex As Exception
    Return False
End Try

结束函数

''注意连接字符串中的初始目录必须为master! '示例默认连接字符串

Dim DefaultConnectionString As String = "Data Source=localhost\SQLSERVER2008;Initial Catalog=Master; User ID=SA; Password='123123'; MultipleActiveResultSets=false; Connect Timeout=15;Encrypt=False;Packet Size=4096;"

1
这个回答与原问题无关,原问题已经存在14年并且有一个被接受的答案。 - Will Blair
这对于其他编写 VB.NET 代码的人非常有用。 - Reagan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接