ตรวจสอบว่ามีตารางอยู่หรือไม่และไม่มีอยู่ให้สร้างใน SQL Server 2008


130

ฉันกำลังเขียนขั้นตอนที่เก็บไว้ใน SQL Server 2008 ฉันต้องการตรวจสอบว่ามีตารางอยู่ในฐานข้อมูลหรือไม่ ถ้าไม่เป็นเช่นนั้นฉันต้องสร้างมันขึ้นมา

ฉันต้องทำอย่างไร


2
ที่เกี่ยวข้องถ้าไม่ซ้ำ: ตรวจสอบว่ามีตารางใน SQL Serverหรือไม่

1
นี่เป็นคำถามที่ดีที่ทุกคนที่ทำงานกับ SQL Server จะถามในที่สุด เป็นเรื่องน่าเศร้าที่ SQL Server ไม่มีสไตล์ Oracle ที่เป็นมิตร CREATE OR REPLACE
Davos

1
สำหรับ MySQL คุณสามารถใช้ได้CREATE TABLE IF NOT EXISTS ...
John Henckel

คำตอบ:


150

อะไรทำนองนี้

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 = 'U'แทนการพิมพ์ใน (N'U ') (คอลัมน์ _typeเป็นประเภทcharโดยใช้ Nchar ทำให้เกิดการแปลงโดยนัยซึ่งมักทำให้เกิดปัญหากับตัวประมาณค่าคาร์ดินาลลิตี้)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 vs. sysobjects vs. sys.all_objects vs. 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) แต่ดูเหมือนว่าแร่จะชัดเจนและกะทัดรัด มีเหตุผลใดที่ไม่ชอบวิธีนี้มากกว่าคำตอบที่ยอมรับ? (เช่นปัญหาความเข้ากันได้กับการย้าย SQL ไปยังผู้ให้บริการ DB ความเร็ว ฯลฯ )
jedd.ahyoung

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 ในสกีมาทั้งหมดในฐานข้อมูลปัจจุบัน แทนที่จะเป็นเช่นนี้หากคุณต้องการตรวจสอบการมีอยู่ของตารางใน Schema ที่ระบุและฐานข้อมูลที่ระบุเราสามารถเขียนแบบสอบถามด้านบนได้ดังนี้:

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()ฟังก์ชันคือ: มีตัวเลือกในการตรวจสอบการมีอยู่ของตารางชั่วคราวซึ่งสร้างขึ้นในบริบทการเชื่อมต่อปัจจุบัน แนวทางอื่น ๆ ทั้งหมดตรวจสอบการมีอยู่ของตารางชั่วคราวที่สร้างขึ้นในบริบทการเชื่อมต่อทั้งหมดแทนที่จะเป็นเพียงบริบทการเชื่อมต่อปัจจุบัน แบบสอบถามด้านล่างแสดงวิธีตรวจสอบการมีอยู่ของตารางชั่วคราวโดยใช้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 Catalog View

เราสามารถใช้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 ตารางมุมมองแค็ตตาล็อก

เราสามารถใช้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จะส่งคืนแถวสำหรับวัตถุ Table เท่านั้นในขณะที่Sys.Objectมุมมองนอกเหนือจากการส่งคืนแถวสำหรับวัตถุตารางจะส่งคืนแถวสำหรับวัตถุเช่น: ขั้นตอนการจัดเก็บมุมมอง ฯลฯ

แนวทางที่ 5: หลีกเลี่ยงการใช้ตารางระบบ sys.sysobjects

เราควรหลีกเลี่ยงการใช้sys.sysobjectsSystem Table โดยตรงการเข้าถึงโดยตรงจะถูกเลิกใช้ใน 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


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.objects, sys.tables) สำหรับรหัสที่จะกำหนดเป้าหมาย 2008 อินสแตนซ์ของ SQL Server และมุมมองสคีข้อมูล (เช่นinformation_schema.tables) สำหรับรหัสที่ความต้องการที่จะพกพา คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับมุมมองต่างๆได้ที่นี่: การสืบค้น SQL Server System Catalog
ajk

-2

ถ้าฉันไม่ผิดสิ่งนี้ควรได้ผล:

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

2
จะเกิดอะไรขึ้นถ้าตารางมีอยู่ แต่ว่างเปล่าสิ่งนี้จะเป็นจริงในกรณีนั้น
SQLMenace

@SQLMeance โอเคฉันเข้าใจจากคำตอบของคุณว่าคุณกำลังตรวจหาประเภท 'U' ในระบบวัตถุคุณช่วยฉันเข้าใจได้ไหมทำไมคุณถึงแนะนำสิ่งนี้ และตารางสามารถอยู่ที่อื่นได้หรือไม่? ขอบคุณล่วงหน้า
RaM
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.