2011-05-10 29 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

相關問題