2011-05-10 34 views
99

我在sql server 2008中编写Stored procedure 我需要检查数据库中是否存在table,如果它不存在我需要创建它。如何检查表是否存在,如果它不存在在sql server 2008中创建表

我该怎么做?

+1

相关,如果不重复的:检查表中的SQL Server中存在(http://stackoverflow.com/q/167576/456814)。 – 2015-10-21 10:03:57

+1

这是一个很好的问题,每个使用SQL Server的人最终都会问。很遗憾,SQL Server没有友好的Oracle风格CREATE OR REPLACE – Davos 2015-11-20 02:26:40

+0

对于MySQL,您可以使用'CREATE TABLE IF NOT EXISTS ...' – 2017-06-26 23:58:32

回答

119

像这样的事情

IF NOT EXISTS (SELECT * FROM sys.objects 
WHERE object_id = OBJECT_ID(N'[dbo].[YourTable]') AND type in (N'U')) 

BEGIN 
CREATE TABLE [dbo].[YourTable](
    .... 
    .... 
    .... 
) 

END 
-2

如果我没看错,这应该工作:

if not exists (Select 1 from tableName) 
create table ... 
+2

如果表存在但是为空,那么这将是真实的 – SQLMenace 2011-05-10 14:58:34

+0

@SQLMeance噢好吧,我从你的回答中了解到你正在检查sys.objects中的'U'类型,你能帮我理解,为什么你推荐这个?并且可以在其他地方存在表吗?预先感谢您 – RaM 2011-05-10 15:01:28

+0

U =用户表,请看这里http://msdn.microsoft.com/en-us/library/ms190324.aspx – SQLMenace 2011-05-10 15:37:48

0

试试下面的语句来检查在数据库中的表的存在:

If not exists (select name from sysobjects where name = 'tablename') 

您可以在if块内创建表格。

+3

虽然这种语法将起作用,但是“sysobjects”是一个兼容性视图,它只是为了避免破坏旧代码。我的建议是针对仅针对SQL Server 2008实例的代码和针对需要的代码的信息模式视图(例如'information_schema.tables')使用系统目录视图(例如'sys.objects','sys.tables')便携。您可以在这里找到有关不同视图的更多信息:[查询SQL Server系统目录](http://msdn.microsoft.com/zh-cn/library/ms189082.aspx) – ajk 2011-05-10 15:44:09

122

只是为了对比,我喜欢使用object_id函数,如下所示。阅读起来要容易一点,你不必担心sys.objects与sysobjects与sys.all_objects 与sys.tables。基本形式:

IF object_id('MyTable') is not null 
    PRINT 'Present!' 
ELSE 
    PRINT 'Not accounted for' 

当然,这将显示为“存在”,如果有任何目前使用该名称的对象。如果您想检查只是表,你需要:

IF object_id('MyTable', 'U') is not null 
    PRINT 'Present!' 
ELSE 
    PRINT 'Not accounted for' 

它适用于临时表,以及:

IF object_id('tempdb.dbo.#MyTable') is not null 
    PRINT 'Present!' 
ELSE 
    PRINT 'Not accounted for' 
+5

OBJECT_ID()参考:http:// msdn.microsoft.com/en-us/library/ms190328.aspx – gonsalu 2011-05-10 16:16:47

+3

这很完美。谢谢。 – djangofan 2011-08-26 23:05:37

+2

我通常会看到使用的其他方法(检查sys表格),但这看起来很清晰且紧凑。有什么理由不喜欢这种方法而不是接受的答案? (如SQL迁移到不同数据库提供者的兼容性问题,速度等)? – 2014-07-07 13:36:31

11

EDITED

你可以看看SYS.TABLES为检查是否存在所需表格:

IF NOT EXISTS (SELECT * FROM sys.tables 
WHERE name = N'YourTable' AND type = 'U') 

BEGIN 
CREATE TABLE [SchemaName].[YourTable](
    .... 
    .... 
    .... 
) 

END 
2
IF (EXISTS (SELECT * 
       FROM INFORMATION_SCHEMA.TABLES 
       WHERE TABLE_NAME = 'd020915')) 
BEGIN 
    declare @result int 
    set @result=1 
    select @result as result 
END 
7

让我们通过下面的脚本创建一个表的样本数据库:

CREATE DATABASE Test 
GO 
USE Test 
GO 
CREATE TABLE dbo.tblTest (Id INT, Name NVARCHAR(50)) 

方法1:使用INFORMATION_SCHEMA.TABLES查看

我们可以编写一个查询类似下面来检查TBLTEST表存在于当前数据库中。

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'tblTest') 
BEGIN 
    PRINT 'Table Exists' 
END 

以上查询检查当前数据库中所有模式中是否存在tblTest表。取而代之的是,如果你想检查表是否存在在特定模式和指定的数据库,然后我们可以写如下上面的查询:

这种方法的
IF EXISTS (SELECT * FROM Test.INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = N'dbo' AND TABLE_NAME = N'tblTest') 
BEGIN 
    PRINT 'Table Exists' 
END 

优点:INFORMATION_SCHEMA欣赏到不同的RDBMS是便携式系统,因此移植到不同的RDBMS不需要任何更改。

方法二:使用OBJECT_ID()函数

我们可以使用OBJECT_ID()功能类似下面来检查TBLTEST表在当前数据库中存在。

IF OBJECT_ID(N'dbo.tblTest', N'U') IS NOT NULL 
BEGIN 
    PRINT 'Table Exists' 
END 

指定表名的数据库名称和架构名称部分是可选的。但是指定数据库名称和架构名称提供了一个选项,用于检查指定数据库中和指定架构内表的存在情况,而不是检查所有架构中的当前数据库。以下查询显示即使当前数据库是MASTER数据库,我们也可以检查Test数据库中dbo模式中tblTest表的存在性。

USE MASTER 
GO 
IF OBJECT_ID(N'Test.dbo.tblTest', N'U') IS NOT NULL 
BEGIN 
    PRINT 'Table Exists' 
END 

优点:易于记忆。关于OBJECT_ID()函数的另一个值得注意的地方是:它提供了一个选项来检查在当前连接上下文中创建的临时表的存在。所有其他方法检查跨所有连接上下文而不是仅当前连接上下文创建的临时表的存在。下面的查询显示了如何使用OBJECT_ID()功能检查临时表的存在:

CREATE TABLE #TempTable(ID INT) 
GO 
IF OBJECT_ID(N'TempDB.dbo.#TempTable', N'U') IS NOT NULL 
BEGIN 
    PRINT 'Table Exists' 
END 
GO 

方法3:使用sys.objects中目录视图

我们可以使用Sys.Objects目录视图,以检查是否存在如以下所示的表:

IF EXISTS(SELECT 1 FROM sys.Objects WHERE Object_id = OBJECT_ID(N'dbo.tblTest') AND Type = N'U') 
BEGIN 
    PRINT 'Table Exists' 
END 

方法4:使用SYS.TABLES目录视图

我们可以使用Sys.Tables目录视图检查表的存在,如下所示:

IF EXISTS(SELECT 1 FROM sys.Tables WHERE Name = N'tblTest' AND Type = N'U') 
BEGIN 
    PRINT 'Table Exists' 
END 

Sys.Tables目录视图继承了Sys.Objects目录视图中的行,Sys.objects目录视图被称为基本视图其中sys.Tables被称为派生视图。 Sys.Tables将只对表的对象而Sys.Object视图返回行除了返回为表格对象的行中,它对于像中的对象返回行:存储过程,视图等

方法5:避免使用sys.sysobjects系统表

我们应该避免直接使用sys.sysobjects系统表,直接访问它将在以后的某些版本的Sql Server中被弃用。根据[Microsoft BOL] [1]链接,Microsoft建议直接使用目录视图sys.objects/sys.tables而不是sys.sysobjects系统表。

IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = N'tblTest' AND xtype = N'U') 
BEGIN 
    PRINT 'Table Exists' 
END 

参考:http://sqlhints.com/2014/04/13/how-to-check-if-a-table-exists-in-sql-server/

+0

重要的是要注意,这个答案提供了哪种方法需要指定数据库,哪些不需要。这对于在同一个实例中运行同一数据库的多个数据库时运行以设置和更新操作数据库的脚本非常有用,这是关键!伟大的信息。 – 2017-12-29 16:43:34

相关问题