テーブルが存在するかどうかを確認し、存在しない場合は、SQL Server 2008で作成します。


130

SQL Server 2008でストアドプロシージャを書いています。データベースにテーブルが存在するかどうかを確認する必要があります。そうでない場合は、作成する必要があります。

どうすればよいですか?



1
これは、SQL Serverを使用するすべての人が最終的に尋ねる素晴らしい質問です。SQL Serverに親しみやすいOracleスタイルのCREATE OR REPLACEがないことは悲しいことです
ダボス

1
MySQLの場合に使用できますCREATE TABLE IF NOT EXISTS ...
John Henckel 2017年

回答:


148

このようなもの

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

1
*の代わりにインデックス付きフィールドを使用して(実行計画のために)いくつかの変更を慎重に検討してください(object_idはこのテーブルで一般的に参照される数値フィールドです)type in(N'U ')ではなくtype =' U 'を使用します。(列_typeはタイプNcharを使用するchar型であり、暗黙的な変換が行われるため、カーディナリティエスティメータで問題が発生することが多い)if (not exists (select object_id from sys.objects where object_id = OBJECT_ID(N'[dbo].[client_tgi_g67_period_list]') and type = 'U'))
yeOldeDataSmythe

153

対照的に、以下に示すように、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'

2
私は通常、他の方法(sysテーブルのチェック)を使用しているのを目にしていますが、これは鉱石が読みやすくコンパクトなようです。受け入れられた回答よりもこの方法を好まない理由はありますか?(異なるDBプロバイダーへのSQL移行、速度などの互換性の問題など)?
jedd.ahyoung 2014

16

以下のスクリプトでテーブルを含むサンプルデータベースを作成してみましょう。

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への移植に変更は必要ありません。

アプローチ2:OBJECT_ID()関数を使用する

OBJECT_ID()以下のような関数を使用して、tblTestテーブルが現在のデータベースに存在するかどうかを確認できます。

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

テーブル名のデータベース名とスキーマ名の部分の指定はオプションです。ただし、データベース名とスキーマ名を指定すると、すべてのスキーマにわたって現在のデータベースをチェックインする代わりに、指定されたデータベースと指定されたスキーマ内のテーブルの存在をチェックするオプションが提供されます。以下のクエリは、現在のデータベースがMASTERデータベースであっても、データベースtblTest内のdboスキーマにテーブルが存在することを確認できることを示していますTest

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

長所:覚えやすい。OBJECT_ID()関数に関するもう1つの注目すべき点は、現在の接続コンテキストで作成された一時テーブルの存在を確認するオプションを提供することです。他のすべてのアプローチは、現在の接続コンテキストだけでなく、すべての接続コンテキストにわたって作成された一時テーブルの存在をチェックします。以下のクエリは、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/


この回答では、データベースを指定する必要がある方法と指定しない方法が示されていることに注意してください。これは非常に価値があり、同じインスタンスで同じデータベースが複数実行されているときに、稼働中のデータベースをセットアップおよび更新するために実行されるスクリプトにとって、これが重要です。素晴らしい情報。
Nelda.techspiress

11

編集済み

sys.tablesを調べて、目的のテーブルの存在を確認できます。

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

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

END

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

1
Declare @Username varchar(20)
Set @Username = 'Mike'

if not exists 
(Select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'tblEmp')

Begin
    Create table tblEmp (ID int primary key, Name varchar(50))
    Print (@Username + ' Table created successfully')
End

Else

Begin
    Print (@Username + ' : this Table Already exists in the database')
End

1
StackOverflowへようこそ。質問に答えるときは、説明も追加することを検討してください。ほとんどの場合、コードだけではあまり役に立ちません。
Viktor

0

次のステートメントを試して、データベース内にテーブルが存在するかどうかを確認します。

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

ifブロック内にテーブルを作成できます。


3
その構文は機能しますが、sysobjects古いコードの破損を回避するためにのみ存在する互換ビューです。私の提案はsys.objectssys.tablesSQL Server 2008インスタンスのみを対象とするコードにはシステムカタログビュー(など)を使用し、information_schema.tables移植性が必要なコードには情報スキーマビュー(たとえば)を使用することです。さまざまなビューの詳細については、こちらをご覧ください
。SQLServer

-2

私が間違っていなければ、これはうまくいくはずです:

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

2
どのような表が存在するが空の場合は,,これは、その場合にtrueになります
SQLMenace

@SQLMeanceわかりました。あなたの答えから、sys.objectsのタイプ 'U'をチェックしていることがわかりました。なぜこれをお勧めするのか、理解してもらえますか?そして、テーブルはどこにでも存在できますか?事前にありがとう
RaM
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.