Kiểm tra xem bảng có tồn tại không và nếu nó không tồn tại, hãy tạo nó trong SQL Server 2008


130

Tôi đang viết một thủ tục được lưu trữ trong SQL Server 2008. Tôi cần kiểm tra xem một bảng có tồn tại trong cơ sở dữ liệu hay không. Nếu nó không thì tôi cần phải tạo ra nó.

Làm thế nào để tôi làm điều này?


2
Liên quan, nếu không trùng lặp: Kiểm tra xem bảng có tồn tại trong SQL Server không .

1
Đây là một câu hỏi tuyệt vời mà mọi người làm việc với SQL Server cuối cùng sẽ hỏi. Thật đáng buồn khi SQL Server không có kiểu Oracle thân thiện TẠO HOẶC THAY THẾ
Davos

1
Đối với MySQL, bạn có thể sử dụngCREATE TABLE IF NOT EXISTS ...
John Henckel

Câu trả lời:


148

Một cái gì đó như thế này

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
trân trọng xem xét một vài thay đổi (vì lợi ích của kế hoạch thực hiện) bằng cách sử dụng trường được lập chỉ mục thay vì * (object_id là trường số thường được giới thiệu trong bảng này) sử dụng type = 'U' thay vì gõ trong (N'U ') (cột _type thuộc loại char sử dụng Nchar gây ra chuyển đổi ngầm thường gây ra sự cố với công cụ ước tính cardinality)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

Để tương phản, tôi thích sử dụng hàm object_id như dưới đây. Nó dễ đọc hơn một chút và bạn không phải lo lắng về sys.objects so với sysobjects so với sys.all_objects so với sys.tables. Hình thức cơ bản:

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

Tất nhiên điều này sẽ hiển thị là "Hiện tại" nếu có bất kỳ đối tượng nào có tên đó. Nếu bạn muốn kiểm tra chỉ các bảng, bạn cần:

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

Nó cũng hoạt động cho các bảng tạm thời:

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

2
Tôi thường thấy phương pháp khác được sử dụng (kiểm tra các bảng sys) nhưng điều này có vẻ dễ đọc và nhỏ gọn. Có lý do nào để không thích phương pháp này hơn câu trả lời được chấp nhận không? (Chẳng hạn như các vấn đề tương thích với di chuyển SQL đến các nhà cung cấp DB khác nhau, tốc độ, v.v.)?
jedd.ahyoung

16

Hãy để chúng tôi tạo một cơ sở dữ liệu mẫu với một bảng theo kịch bản dưới đây:

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

Cách tiếp cận 1: Sử dụng chế độ xem Information_SCHema.TABLES

Chúng ta có thể viết một truy vấn như dưới đây để kiểm tra xem Bảng tblTest có tồn tại trong cơ sở dữ liệu hiện tại không.

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

Truy vấn trên kiểm tra sự tồn tại của bảng tblTest trên tất cả các lược đồ trong cơ sở dữ liệu hiện tại. Thay vì điều này nếu bạn muốn kiểm tra sự tồn tại của Bảng trong Lược đồ được chỉ định và Cơ sở dữ liệu được chỉ định thì chúng ta có thể viết truy vấn trên như dưới đây:

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

Ưu điểm của phương pháp này: Các khung nhìn Information_SCHema có thể di động trên các hệ thống RDBMS khác nhau, do đó, việc chuyển sang RDBMS khác nhau không yêu cầu bất kỳ thay đổi nào.

Cách tiếp cận 2: Sử dụng hàm OBJECT_ID ()

Chúng ta có thể sử dụng OBJECT_ID()chức năng như dưới đây để kiểm tra xem Bảng tblTest có tồn tại trong cơ sở dữ liệu hiện tại không.

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

Chỉ định các phần Tên cơ sở dữ liệu và Tên lược đồ cho Tên bảng là tùy chọn. Nhưng việc chỉ định Tên cơ sở dữ liệu và Tên lược đồ cung cấp một tùy chọn để kiểm tra sự tồn tại của bảng trong cơ sở dữ liệu đã chỉ định và trong một lược đồ đã chỉ định, thay vì kiểm tra trong cơ sở dữ liệu hiện tại trên tất cả các lược đồ. Truy vấn dưới đây cho thấy rằng mặc dù cơ sở dữ liệu hiện tại là cơ sở dữ liệu MASTER, chúng ta có thể kiểm tra sự tồn tại của tblTestbảng trong dbolược đồ trong Testcơ sở dữ liệu.

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

Ưu điểm: Dễ nhớ. Một điểm đáng chú ý khác cần đề cập về OBJECT_ID()chức năng là: nó cung cấp tùy chọn để kiểm tra sự tồn tại của Bảng tạm thời được tạo trong ngữ cảnh kết nối hiện tại. Tất cả các Cách tiếp cận khác kiểm tra sự tồn tại của Bảng tạm thời được tạo trên tất cả bối cảnh kết nối thay vì chỉ bối cảnh kết nối hiện tại. Dưới đây truy vấn cho thấy cách kiểm tra sự tồn tại của Bảng tạm thời bằng cách sử dụng OBJECT_ID()chức năng:

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

Cách tiếp cận 3: Sử dụng sys.Objects Danh mục xem

Chúng ta có thể sử dụng Sys.Objectskhung nhìn danh mục để kiểm tra sự tồn tại của Bảng như dưới đây:

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

Cách tiếp cận 4: Sử dụng sys.Tables Xem danh mục

Chúng ta có thể sử dụng Sys.Tableskhung nhìn danh mục để kiểm tra sự tồn tại của Bảng như dưới đây:

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

Sys.TablesChế độ xem danh mục kế thừa các hàng từ Sys.Objectschế độ xem danh mục, chế độ xem Sys.objectsdanh mục được gọi là chế độ xem cơ sở trong đó sys.Tablesđược gọi là chế độ xem dẫn xuất. Sys.Tablessẽ chỉ trả về các hàng cho các đối tượng Bảng trong khi Sys.Objectxem ngoài việc trả lại các hàng cho các đối tượng bảng, nó sẽ trả về các hàng cho các đối tượng như: thủ tục được lưu trữ, các khung nhìn, v.v.

Cách tiếp cận 5: Tránh sử dụng sys.sysobjects Bảng hệ thống

Chúng ta nên tránh sử dụng sys.sysobjectsBảng hệ thống trực tiếp, quyền truy cập trực tiếp vào Bảng sẽ bị phản đối trong một số phiên bản tương lai của Máy chủ Sql. Theo liên kết [Microsoft BOL] [1], Microsoft đang đề xuất sử dụng các chế độ xem danh mục sys.objects/sys.tablesthay vì sys.sysobjectstrực tiếp bảng hệ thống.

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

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


Điều quan trọng cần lưu ý là câu trả lời này cung cấp cách tiếp cận nào cần cơ sở dữ liệu được chỉ định và phương pháp nào không. Điều này là vô cùng có giá trị và đối với các tập lệnh chạy để thiết lập và cập nhật cơ sở dữ liệu hoạt động khi có nhiều cơ sở dữ liệu giống nhau chạy trên cùng một ví dụ, đây là chìa khóa! Thông tin tuyệt vời.
Nelda.techspiress

11

EDITED

Bạn có thể xem xét sys.tables để kiểm tra bảng tồn tại mong muốn:

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
Chào mừng bạn đến với StackOverflow. Khi trả lời câu hỏi, hãy xem xét thêm một lời giải thích. Mã một mình không phải là rất hữu ích hầu hết thời gian.
Viktor

0

Hãy thử câu lệnh sau để kiểm tra sự tồn tại của bảng trong cơ sở dữ liệu:

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

Bạn có thể tạo bảng bên trong khối if.


3
Trong khi cú pháp đó sẽ hoạt động, sysobjectslà một khung nhìn tương thích chỉ tồn tại để tránh phá vỡ mã cũ hơn. Đề nghị của tôi sẽ được hệ thống quan điểm sử dụng Danh mục (ví dụ sys.objects, sys.tables) cho mã đó sẽ chỉ nhắm mục tiêu SQL Server instance 2008, và quan điểm schema thông tin (ví dụ information_schema.tables) cho mã mà nhu cầu để được cầm tay. Bạn có thể tìm thêm thông tin về các chế độ xem khác nhau tại đây: Truy vấn Danh mục hệ thống máy chủ SQL
ajk

-2

Nếu tôi không sai, điều này sẽ hoạt động:

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

2
Điều gì xảy ra nếu bảng tồn tại nhưng trống rỗng, điều này sẽ đúng trong trường hợp đó
SQLMenace

@QueryMeance Oh ok, tôi hiểu từ câu trả lời của bạn rằng bạn đang kiểm tra loại 'U' trong sys.objects, bạn có thể giúp tôi hiểu, tại sao bạn lại khuyên bạn điều này không? và một bảng có thể tồn tại bất cứ nơi nào khác? Cảm ơn bạn trước
RaM
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.