Tablonun var olup olmadığını kontrol edin ve yoksa SQL Server 2008'de oluşturun


130

SQL Server 2008'de Depolanan bir prosedür yazıyorum. Veritabanında bir tablo olup olmadığını kontrol etmem gerekiyor. Olmazsa, onu yaratmam gerekir.

Bunu nasıl yaparım?


2
Yinelenmemişse ilgili: SQL Server'da tablo olup olmadığını kontrol edin .

1
Bu, SQL Server ile çalışan herkesin er ya da geç soracağı harika bir sorudur. SQL Server'ın CREATE OR DEĞİŞTİR, dostça Oracle stiline sahip olmaması üzücü
Davos

1
MySQL için kullanabilirsinizCREATE TABLE IF NOT EXISTS ...
John Henckel

Yanıtlar:


150

Bunun gibi bir şey

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
* yerine dizine alınmış bir alan kullanarak birkaç değişikliği dikkate alın (yürütme planı uğruna) (nesne_kimliği , bu tabloda yaygın olarak atıfta bulunulan sayısal alandır) yazın (N'U ') yerine type =' U ' kullanın (_type sütunu , Nchar kullanan char türünde bir örtük dönüşüme neden olur ve bu da genellikle kardinalite tahmincisinde sorunlara neden olur)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

Sadece kontrast için, aşağıda gösterildiği gibi object_id işlevini kullanmayı seviyorum. Okuması biraz daha kolay ve sys.objects, sysobjects, sys.all_objects ve sys.tables hakkında endişelenmenize gerek yok. Temel biçim:

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

Tabii ki bu isimde herhangi bir nesne varsa bu "Mevcut" olarak gösterilecektir . Yalnızca tabloları kontrol etmek istiyorsanız şunlara ihtiyacınız vardır:

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

Geçici tablolar için de çalışır:

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

2
Genelde kullanılan diğer yöntemi görüyorum (sistem tablolarını kontrol ederek) ama bu okunaklı ve kompakt görünüyor. Kabul edilen cevap yerine bu yöntemi tercih etmemek için herhangi bir sebep var mı? (Farklı veritabanı sağlayıcılarına SQL geçişi, hız, vb. İle ilgili uyumluluk sorunları gibi)?
jedd.ahyoung

16

Aşağıdaki komut dosyası ile bir tablo ile örnek bir veritabanı oluşturalım:

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

Yaklaşım 1: INFORMATION_SCHEMA.TABLES görünümünü kullanma

Mevcut veritabanında tblTest Tablosu olup olmadığını kontrol etmek için aşağıdaki gibi bir sorgu yazabiliriz.

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

Yukarıdaki sorgu, geçerli veritabanındaki tüm şemalarda tblTest tablosunun varlığını kontrol eder. Bunun yerine Tablonun belirli bir Şema ve Belirtilen Veritabanındaki varlığını kontrol etmek isterseniz yukarıdaki sorguyu aşağıdaki gibi yazabiliriz:

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

Bu Yaklaşımın Artıları: INFORMATION_SCHEMA görünümleri farklı RDBMS sistemlerinde taşınabilir, bu nedenle farklı RDBMS'ye taşıma herhangi bir değişiklik gerektirmez.

Yaklaşım 2: OBJECT_ID () işlevini kullanma

OBJECT_ID()Mevcut veritabanında bir tblTest Tablosu olup olmadığını kontrol etmek için aşağıdaki gibi işlevi kullanabiliriz .

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

Tablo Adı için Veritabanı Adı ve Şema Adı bölümlerinin belirtilmesi isteğe bağlıdır. Ancak Veritabanı Adı ve Şema Adının belirtilmesi, tüm şemalarda geçerli veritabanını kontrol etmek yerine, tablonun belirtilen veritabanında ve belirli bir şema içinde varlığını kontrol etme seçeneği sağlar. Aşağıdaki sorgu, mevcut veritabanı MASTER veritabanı olsa bile , veritabanındaki şemadaki tblTesttablonun varlığını kontrol edebileceğimizi göstermektedir .dboTest

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

Artıları: Hatırlaması kolay. OBJECT_ID()İşlev hakkında belirtilmesi gereken bir diğer önemli nokta şudur: mevcut bağlantı bağlamında oluşturulan Geçici Tablonun varlığını kontrol etme seçeneği sunar. Diğer tüm Yaklaşımlar, yalnızca mevcut bağlantı bağlamı yerine tüm bağlantı bağlamında oluşturulan Geçici Tablonun varlığını kontrol eder. Aşağıdaki sorgu, OBJECT_ID()işlevi kullanarak Geçici Tablonun varlığının nasıl kontrol edileceğini gösterir :

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

Yaklaşım 3: sys.Objects Katalog Görünümünü Kullanma

Sys.ObjectsAşağıda gösterildiği gibi Tablonun varlığını kontrol etmek için katalog görünümünü kullanabiliriz :

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

Yaklaşım 4: sys.Tables Katalog Görünümünü Kullanma

Sys.TablesAşağıda gösterildiği gibi Tablonun varlığını kontrol etmek için katalog görünümünü kullanabiliriz :

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

Sys.Tableskatalog görünümü, satırları katalog görünümünden devralır Sys.Objects, Sys.objectskatalog görünümü, sys.Tablestüretilmiş görünüm olarak anılan temel görünüm olarak adlandırılır. Sys.Tablessatırları yalnızca Tablo nesneleri için döndürürken, Sys.Objectgörünüm tablo nesneleri için satırları döndürmekten ayrı olarak, saklı yordam, görünümler vb.

Yaklaşım 5: sys.sysobjects Sistem tablosunu kullanmaktan kaçının

sys.sysobjectsSistem Tablosunu doğrudan kullanmaktan kaçınmalıyız , ona doğrudan erişim Sql Sunucusunun gelecekteki bazı sürümlerinde kullanımdan kaldırılacaktır. [Microsoft BOL] [1] bağlantısına göre Microsoft, doğrudan sistem tablosu sys.objects/sys.tablesyerine katalog görünümlerinin kullanılmasını önermektedir sys.sysobjects.

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

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


Bu cevabın, hangi yaklaşımın veri tabanının belirlenmesini gerektirdiğini ve hangilerinin gerekmediğini sağladığına dikkat etmek önemlidir. Bu son derece değerlidir ve aynı örnekte birden fazla aynı veritabanının çalıştığı durumlarda operasyonel bir veritabanını kurmak ve güncellemek için çalışan komut dosyaları için anahtar budur! Harika bilgiler.
Nelda.techspiress

11

REDAKTE

İstenen tablonun varlığını kontrol etmek için sys.tables'a bakabilirsiniz :

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'a hoş geldiniz. Soruları cevaplarken bir açıklama da eklemeyi düşünün. Tek başına kod çoğu zaman pek yardımcı olmaz.
Viktor

0

Veritabanında bir tablonun varlığını kontrol etmek için aşağıdaki ifadeyi deneyin:

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

Tabloyu if bloğunun içinde oluşturabilirsiniz.


3
Bu sözdizimi işe yarayacak olsa da, sysobjectsyalnızca eski kodu bozmamak için var olan bir uyumluluk görünümüdür. Önerim , yalnızca SQL Server 2008 örneklerini hedefleyen kod için sistem kataloğu görünümlerini (örn sys.objects. sys.tables) Ve information_schema.tablestaşınabilir olması gereken kod için bilgi şeması görünümlerini (örn. ) Kullanmak olacaktır. Farklı görünümler hakkında daha fazla bilgiyi burada bulabilirsiniz: SQL Server Sistem Kataloğunu Sorgulama
ajk

-2

Yanılmıyorsam, bu işe yaramalı:

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

2
ya tablo mevcutsa ancak boşsa, bu durumda bu doğru olacaktır
SQLMenace

@SQLMeance Oh tamam, cevabınızdan sys.objects'te 'U' türünü kontrol ettiğinizi anlıyorum, anlamama yardımcı olabilir misiniz, bunu neden tavsiye ediyorsunuz? ve bir masa başka bir yerde olabilir mi? Şimdiden teşekkür ederim
RaM
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.