Periksa apakah tabel ada dan jika tidak ada, buat di SQL Server 2008

130

Saya menulis prosedur tersimpan dalam SQL Server 2008. Saya perlu memeriksa apakah ada tabel di database. Jika tidak maka saya harus membuatnya.

Bagaimana saya melakukan ini?

Prady
sumber
2
Terkait, jika tidak duplikat: Periksa apakah tabel ada di SQL Server .
1
Ini adalah pertanyaan besar yang semua orang yang bekerja dengan SQL Server akan bertanya. Sangat menyedihkan bahwa SQL Server tidak memiliki gaya Oracle yang ramah. BUAT ATAU GANTI
Davos
1
Untuk MySQL, Anda dapat menggunakanCREATE TABLE IF NOT EXISTS ...
John Henckel

Jawaban:

148

Sesuatu seperti ini

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
SQLMenace
sumber
1
dengan hormat pertimbangkan beberapa perubahan (demi rencana eksekusi) menggunakan bidang yang diindeks alih-alih * (object_id adalah bidang numerik yang biasa disebut dalam tabel ini) menggunakan tipe = 'U' alih-alih mengetikkan (N'U ') (kolom _type bertipe char menggunakan Nchar menyebabkan konversi implisit yang sering menyebabkan masalah dengan penaksir kardinalitas)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

Hanya untuk kontras, saya suka menggunakan fungsi object_id seperti yang ditunjukkan di bawah ini. Ini sedikit lebih mudah dibaca, dan Anda tidak perlu khawatir tentang sys.objects vs sysobjects vs sys.all_objects vs sys.tables. Bentuk dasar:

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

Tentu saja ini akan menunjukkan sebagai "Hadir" jika ada setiap objek hadir dengan nama itu. Jika Anda ingin memeriksa tabel saja, Anda perlu:

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

Ini berfungsi untuk tabel temp juga:

IF object_id('tempdb.dbo.#MyTable') is not null
    PRINT 'Present!'
ELSE
    PRINT 'Not accounted for'
Philip Kelley
sumber
2
Saya biasanya melihat metode lain yang digunakan (memeriksa tabel sys) tetapi ini tampaknya dapat dibaca dan ringkas. adakah alasan untuk tidak memilih metode ini daripada jawaban yang diterima? (Seperti masalah kompatibilitas dengan migrasi SQL ke berbagai penyedia DB, kecepatan, dll)?
jedd.ahyoung
16

Mari kita buat contoh database dengan tabel dengan skrip di bawah ini:

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

Pendekatan 1: Menggunakan tampilan INFORMATION_SCHEMA.TABLES

Kami dapat menulis kueri seperti di bawah ini untuk memeriksa apakah Tabel tblTest ada di database saat ini.

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

Kueri di atas memeriksa keberadaan tabel tblTest di semua skema di database saat ini. Alih-alih ini jika Anda ingin memeriksa keberadaan Tabel dalam Skema tertentu dan Basis Data Tertentu, maka kami dapat menulis kueri di atas seperti di bawah ini:

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

Kelebihan dari Pendekatan ini: Tampilan INFORMATION_SCHEMA bersifat portabel di seluruh sistem RDBMS yang berbeda, sehingga porting ke RDBMS yang berbeda tidak memerlukan perubahan apa pun.

Pendekatan 2: Menggunakan fungsi OBJECT_ID ()

Kita bisa menggunakan OBJECT_ID()fungsi seperti di bawah ini untuk memeriksa apakah ada Tabel tblTest di database saat ini.

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

Menentukan bagian Nama Database dan Nama Skema untuk Nama Tabel adalah opsional. Tetapi menentukan Nama Basis Data dan Nama Skema memberikan opsi untuk memeriksa keberadaan tabel dalam database yang ditentukan dan dalam skema tertentu, alih-alih memeriksa database saat ini di semua skema. Kueri di bawah ini menunjukkan bahwa meskipun database saat ini adalah database MASTER, kami dapat memeriksa keberadaan tblTesttabel dalam dboskema dalam Testdatabase.

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

Pro: Mudah diingat. Satu hal penting lainnya untuk menyebutkan tentang OBJECT_ID()fungsi adalah: ia menyediakan opsi untuk memeriksa keberadaan Tabel Sementara yang dibuat dalam konteks koneksi saat ini. Semua Pendekatan lain memeriksa keberadaan Tabel Sementara yang dibuat di semua konteks koneksi, bukan hanya konteks koneksi saat ini. Kueri di bawah ini menunjukkan cara memeriksa keberadaan Tabel Sementara menggunakan OBJECT_ID()fungsi:

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

Pendekatan 3: Menggunakan Tampilan Katalog sys.Objects

Kita dapat menggunakan tampilan Sys.Objectskatalog untuk memeriksa keberadaan Tabel seperti yang ditunjukkan di bawah ini:

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

Pendekatan 4: Menggunakan Tampilan Katalog sys.Tables

Kita dapat menggunakan tampilan Sys.Tableskatalog untuk memeriksa keberadaan Tabel seperti yang ditunjukkan di bawah ini:

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

Sys.Tablestampilan katalog mewarisi baris dari tampilan Sys.Objectskatalog, Sys.objectstampilan katalog disebut sebagai tampilan dasar di mana sys.Tablesdisebut sebagai tampilan turunan. Sys.Tablesakan mengembalikan baris hanya untuk objek Tabel sedangkan Sys.Objecttampilan terpisah dari mengembalikan baris untuk objek tabel, ia mengembalikan baris untuk objek seperti: prosedur tersimpan, tampilan dll.

Pendekatan 5: Hindari Menggunakan Tabel Sistem sys.sysobjects

Kita harus menghindari menggunakan sys.sysobjectsTabel Sistem secara langsung, akses langsung ke itu akan ditinggalkan di beberapa versi Sql Server. Sesuai tautan [Microsoft BOL] [1], Microsoft menyarankan untuk menggunakan tampilan katalog sys.objects/sys.tablesalih-alih sys.sysobjectstabel sistem secara langsung.

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

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

Vahid Farahmandian
sumber
Penting untuk dicatat bahwa jawaban ini menyediakan pendekatan mana yang membutuhkan basis data untuk ditentukan dan mana yang tidak. Ini sangat berharga dan untuk skrip yang menjalankan untuk mensetup dan memperbarui database operasional ketika ada beberapa database yang sama berjalan pada contoh yang sama, ini adalah kuncinya! Informasi hebat.
Nelda.techspiress
11

Diedit

Anda dapat melihat sys.tables untuk memeriksa keberadaan tabel yang diinginkan:

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

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

END
veljasije
sumber
3
IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE  TABLE_NAME = 'd020915'))
BEGIN
  declare @result int
  set @result=1
  select @result as result
END
Vinod kumar
sumber
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
Aamir Shaikh
sumber
1
Selamat datang di StackOverflow. Saat menjawab pertanyaan, pertimbangkan untuk menambahkan penjelasan juga. Kode sendiri tidak sangat membantu sebagian besar waktu.
Viktor
0

Coba pernyataan berikut untuk memeriksa keberadaan tabel di database:

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

Anda dapat membuat tabel di dalam blok if.

Hanya kamu
sumber
3
Sementara sintaks itu akan berfungsi, sysobjectsadalah tampilan kompatibilitas yang hanya ada untuk menghindari melanggar kode yang lebih lama. Saran saya adalah menggunakan tampilan katalog sistem (misalnya sys.objects, sys.tables) untuk kode yang hanya akan menargetkan instance SQL Server 2008, dan tampilan skema informasi (misalnya information_schema.tables) untuk kode yang perlu portabel. Anda dapat menemukan informasi lebih lanjut tentang pandangan yang berbeda di sini:
Meminta
-2

Jika saya tidak salah, ini akan berhasil:

    if not exists (Select 1 from tableName)
create table ...
RaM
sumber
2
bagaimana jika tabel ada tetapi kosong ,, ini akan benar dalam kasus itu
SQLMenace
@ SQLMeance Oh ok, saya mengerti dari jawaban Anda bahwa Anda memeriksa tipe 'U' di sys.objects, Bisakah Anda membantu saya mengerti, mengapa Anda merekomendasikan ini? dan dapatkah meja ada di tempat lain? Terima kasih sebelumnya
RaM