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


1143

ฉันต้องการให้เป็นการอภิปรายขั้นสุดท้ายเกี่ยวกับวิธีตรวจสอบว่ามีตารางอยู่ใน SQL Server 2000/2005 โดยใช้คำสั่ง SQL หรือไม่

เมื่อคุณได้รับคำตอบจาก Google คุณจะได้คำตอบที่แตกต่างกันมากมาย มีวิธีอย่างเป็นทางการ / ย้อนกลับและไปข้างหน้าในการทำมัน?

นี่เป็นวิธีที่เป็นไปได้สองวิธี วิธีใดที่หนึ่งในสองคือมาตรฐาน / วิธีที่ดีที่สุดในการทำมัน?

วิธีแรก:

IF EXISTS (SELECT 1 
           FROM INFORMATION_SCHEMA.TABLES 
           WHERE TABLE_TYPE='BASE TABLE' 
           AND TABLE_NAME='mytablename') 
   SELECT 1 AS res ELSE SELECT 0 AS res;

วิธีที่สอง:

IF OBJECT_ID (N'mytablename', N'U') IS NOT NULL 
   SELECT 1 AS res ELSE SELECT 0 AS res;

MySQLจัดเตรียมสิ่งที่ง่าย

SHOW TABLES LIKE '%tablename%'; 

คำให้การ. ฉันกำลังมองหาบางสิ่งที่คล้ายกัน


1
ทำไมจึงเป็นการดีที่สุดที่จะใช้ INFORMATION_SCHEMA.TABLES แทนที่จะเป็น sys.tables แล้วกรองด้วยชื่อใด ๆ ที่อาจเพิ่มการตรวจสอบค่า type_desc?
DanteTheSmith

คำตอบ:


1332

สำหรับคำค้นหาเช่นนี้เป็นการดีที่สุดที่จะใช้INFORMATION_SCHEMAมุมมอง มุมมองเหล่านี้เป็นมาตรฐาน (ส่วนใหญ่) ในฐานข้อมูลที่แตกต่างกันและไม่ค่อยเปลี่ยนจากรุ่นเป็นรุ่น

วิธีตรวจสอบว่ามีตารางใช้หรือไม่:

IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'TheSchema' 
                 AND  TABLE_NAME = 'TheTable'))
BEGIN
    --Do Stuff
END

12
ใช้งานได้ดี! ใน T-SQL (ตอบสนองต่อผู้โพสต์ดั้งเดิม) แม้ว่าจะเป็น TABLE_SCHEMA ไม่ใช่ SCHEMA_NAME ขอบคุณสำหรับทิป.
นิโคลัส Piasecki

10
เนื่องจากชื่อวัตถุเพียงอย่างเดียว (นั่นคือไม่มี schema) จึงไม่รับประกันว่าจะไม่ซ้ำกันไม่มีวิธีที่ปลอดภัย 100% ในการทำเช่นนี้ หากคุณกำลังทำงานกับฐานข้อมูลที่ไม่มีความขัดแย้งในการตั้งชื่อข้าม schemas เพียงแค่ละเว้น "TABLE_SCHEMA = 'TheSchema'" จะทำงานได้ดี
akmad

26
เพื่อตรวจสอบตารางชั่วคราวเราต้องค้นหาฐานข้อมูล tempdb และใช้ตัวดำเนินการ LIKE สำหรับชื่อตารางSELECT * FROM tempdb.INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TheSchema' AND TABLE_NAME LIKE '#TheTable%'
Pierre-Alain Vigeant

4
การตอบสนองด้านล่างที่ใช้ฟังก์ชัน OBJECT_ID ทำงานได้อย่างถูกต้องเกี่ยวกับตาราง temp การเชื่อมต่อ - stackoverflow.com/a/2155299/16147
Rich Rousseau

4
@akmad SQL query compiler จะตรวจสอบตารางก่อนเรียกใช้แบบสอบถามและจะล้มเหลวก่อนที่จะเริ่มต้น
Marc K

278

โปรดทราบว่าหากคุณต้องการตรวจสอบตารางชั่วคราวด้วยเหตุผลใดก็ตามคุณสามารถทำสิ่งนี้ได้:

if OBJECT_ID('tempdb..#test') is not null
 --- temp table exists

10
การใช้วิธีนี้ดูเหมือนว่าจะเคารพต่อลักษณะการเชื่อมต่อของตารางชั่วคราว การโพสต์ก่อนหน้า INFORMATION_SCHEMA แบบสอบถามจะส่งกลับแถวโดยไม่คำนึงถึงการเชื่อมต่อที่สร้างตาราง
Rich Rousseau

238

เรามักจะใช้OBJECT_IDสไตล์นี้นานเท่าที่ฉันจำได้

IF OBJECT_ID('*objectName*', 'U') IS NOT NULL 

16
ฉันเชื่อว่ามันจะเร็ว แต่ก็ไม่ได้พกพามาก มุมมอง schema ข้อมูลรับประกันว่าจะมีอยู่ใน DBRMS ใด ๆ ที่สนับสนุนมาตรฐาน นอกจากนี้ OBJECT_ID ธรรมดาไม่รับประกันวัตถุของตาราง
Joe Pineda

9
ขอบคุณโจฉันสงสัยว่าทำไมคุณถึงใช้ OBJECT_ID กับ INFORMATION_SCHEMA.TABLES กับ sys.tables การชี้ให้เห็นว่า INFORMATION_SCHEMA เป็นส่วนหนึ่งของคำตอบที่เป็นมาตรฐาน BTW เป็นเรื่องตลกหนึ่งในผู้เชี่ยวชาญด้านฐานข้อมูลของเราที่ฉันจะถามคำถามนี้มีนามสกุลเดียวกับคุณต้องเป็นนามสกุลที่ดีสำหรับฐานข้อมูล
Apeiron

24
@JoePineda: แล้วกรณีที่คุณใช้OBJECT_ID('TableName', 'U')ในการรับประกันวัตถุเป็นตาราง
Allon Guralnek

1
@AllonGuralnek ดังนั้นแทนที่จะทำตามมาตรฐานที่เรียบง่ายและพกพาได้เพิ่มข้อมูลที่เป็นความลับเพิ่มอีกไหม?
กำหนด

22
@DustinFineout: คำถามถูกติดแท็กtsqlดังนั้นการพกพาจึงใช้ไม่ได้มาก โดยทั่วไปฉันพบฐานโค้ดแบบพกพาน้อยมากจริง ๆ และถ้าค่าความรัดกุมมีค่าคุณควรแน่ใจว่าได้เขียนIF EXISTSคำค้นหานั้นจากคำตอบที่ยอมรับแล้วซ้ำแล้วซ้ำอีก นอกจากนี้ทุกอย่างจะเป็นความลับจนกว่าคุณจะอ่านเอกสารโดยเฉพาะอย่างยิ่งใน T-SQL (หรือตัวแปรอื่น ๆ จริง ๆ )
Allon Guralnek

132

โปรดดูวิธีการด้านล่าง

วิธีที่ 1: ใช้มุมมอง Information_SCHEMA.TABLES

เราสามารถเขียนแบบสอบถามตามด้านล่างเพื่อตรวจสอบว่ามีตารางลูกค้าอยู่ในฐานข้อมูลปัจจุบันหรือไม่

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

วิธีที่ 2: การใช้ฟังก์ชัน OBJECT_ID ()

เราสามารถใช้ OBJECT_ID () ฟังก์ชั่นด้านล่างเพื่อตรวจสอบตารางลูกค้าที่มีอยู่ในฐานข้อมูลปัจจุบัน

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

วิธีที่ 3: การใช้ sys.Objects ดูแค็ตตาล็อก

เราสามารถใช้มุมมองแคตตาล็อก Sys.Objects เพื่อตรวจสอบการมีอยู่ของตารางดังแสดงด้านล่าง:

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

วิธีที่ 4: การใช้มุมมองแคตตาล็อก sys.Tables

เราสามารถใช้มุมมองแคตตาล็อก Sys.Tables เพื่อตรวจสอบการมีอยู่ของตารางที่แสดงด้านล่าง:

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

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

เราควรหลีกเลี่ยงการใช้ sys.sysobjects System Table โดยตรงการเข้าถึงโดยตรงจะถูกคัดค้านใน Sql Server บางรุ่นในอนาคต ตามลิงค์ Microsoft BOL Microsoft ขอแนะนำให้ใช้มุมมองแคตตาล็อก sys.objects / sys.tables แทน sys.sysobjects ตารางระบบโดยตรง

  IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = N'Customers' 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/


37

กำลังมองหาตารางในฐานข้อมูลอื่น:

if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
    print 'Exists'

26

แค่อยากพูดถึงสถานการณ์หนึ่งที่อาจจะใช้OBJECT_IDวิธีการได้ง่ายขึ้น INFORMATION_SCHEMAมุมมองเป็นวัตถุในแต่ละ database-

มุมมอง schema ของข้อมูลถูกกำหนดไว้ใน schema พิเศษที่ชื่อว่า INFORMATION_SCHEMA สคีมานี้มีอยู่ในแต่ละฐานข้อมูล

https://msdn.microsoft.com/en-us/library/ms186778.aspx

ดังนั้นตารางทั้งหมดที่คุณเข้าถึงโดยใช้

IF EXISTS (SELECT 1 
           FROM [database].INFORMATION_SCHEMA.TABLES 
           WHERE TABLE_TYPE='BASE TABLE' 
           AND TABLE_NAME='mytablename') 
   SELECT 1 AS res ELSE SELECT 0 AS res;

จะสะท้อนสิ่งที่มีอยู่[database]เท่านั้น หากคุณต้องการตรวจสอบว่ามีตารางในฐานข้อมูลอื่นอยู่หรือไม่โดยไม่เปลี่ยนแปลงใน[database]แต่ละครั้งOBJECT_IDจะช่วยให้คุณดำเนินการได้ทันที อดีต

IF OBJECT_ID (N'db1.schema.table1', N'U') IS NOT NULL 
   SELECT 1 AS res ELSE SELECT 0 AS res;

ทำงานเช่นเดียวกับ

IF OBJECT_ID (N'db2.schema.table1', N'U') IS NOT NULL 
   SELECT 1 AS res ELSE SELECT 0 AS res;

SQL Server 2016 แก้ไข :

เริ่มจากปี 2559 Microsoft ทำให้ความสามารถในการตรวจสอบวัตถุที่ไม่มีอยู่ง่ายขึ้นก่อนที่จะลดลงโดยเพิ่มif existsคำหลักลงในdropคำสั่ง ตัวอย่างเช่น,

drop table if exists mytablename

จะทำสิ่งเดียวกันกับOBJECT_ID/ INFORMATION_SCHEMAwrappers ใน 1 บรรทัดของรหัส

https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016/



13

การใช้ Information Schema เป็นวิธี SQL Standard ที่ควรทำดังนั้นจึงควรใช้กับฐานข้อมูลทั้งหมดที่สนับสนุน


12
สิ่งนี้ควรเป็นความคิดเห็น
underscore_d

3
คำตอบนี้ต้องการการปรับปรุง
rory.ap

11
IF EXISTS 
(
    SELECT   * 
    FROM     sys.objects 
    WHERE    object_id = OBJECT_ID(N'[dbo].[Mapping_APCToFANavigator]') 
             AND 
             type in (N'U')
)
BEGIN

    -- Do whatever you need to here.

END

Mapping_APCToFANavigatorที่นี่ในโค้ดข้างต้นชื่อตารางเป็น


2
หากคุณโพสต์โค้ด, XML หรือตัวอย่างข้อมูลโปรดเน้นบรรทัดเหล่านั้นในตัวแก้ไขข้อความและคลิกที่ปุ่ม "ตัวอย่างรหัส" ( { }) บนแถบเครื่องมือตัวแก้ไขเพื่อจัดรูปแบบและเน้นไวยากรณ์!
marc_s

1
โปรดทราบว่าการเข้าถึงตารางระบบอาจถูกยกเลิกใน SQL Server เวอร์ชันในอนาคต ใช้มุมมอง Schema แทน
Olivier Jacot-Descombes

10

หากคุณต้องการทำงานกับฐานข้อมูลอื่น:

DECLARE @Catalog VARCHAR(255)
SET @Catalog = 'MyDatabase'

DECLARE @Schema VARCHAR(255)
SET @Schema = 'dbo'

DECLARE @Table VARCHAR(255)
SET @Table = 'MyTable'

IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES   
    WHERE TABLE_CATALOG = @Catalog 
      AND TABLE_SCHEMA = @Schema 
      AND TABLE_NAME = @Table))
BEGIN
   --do stuff
END

1
คุณแน่ใจไหม? สคีมาข้อมูลในกล่อง 2005 ของฉันส่งคืนแคตตาล็อกปัจจุบันเท่านั้น
quillbreaker

8

ฉันรู้ว่ามันเป็นคำถามเก่า แต่ฉันได้พบความเป็นไปได้นี้หากคุณวางแผนที่จะโทรหาบ่อย

create procedure Table_Exists
@tbl varchar(50)
as
return (select count(*) from sysobjects where type = 'U' and name = @tbl)
go

9
-1 ไม่มีจุดหมายมีขั้นตอนสำหรับสิ่งนี้เพราะมันเป็นรหัสมากที่จะเรียกและใช้ผลตอบแทนเช่นเดียวกับการเลือก ควรใช้ประเภทข้อมูลไม่ได้sysname varchar(50)ไม่ควรใช้sysobjectsมุมมองที่คัดค้านและไม่ต้องคำนึงถึงสคีมา
Martin Smith

6

คุณสามารถใช้รหัสด้านล่าง

IF (OBJECT_ID('TableName') IS NOT NULL )
BEGIN
  PRINT 'Table Exists'
END
ELSE
BEGIN 
  PRINT 'Table NOT Exists'
END

หรือ

IF (EXISTS (SELECT * FROM sys.tables WHERE [name] = 'TableName'))
BEGIN
  PRINT 'Table Exists'
END
ELSE
BEGIN 
  PRINT 'Table NOT Exists'
END

5

เพียงเพิ่มที่นี่เพื่อประโยชน์ของนักพัฒนาและเพื่อน DBAs

สคริปต์ที่ได้รับ @Tablename เป็นพารามิเตอร์

(ซึ่งอาจมีหรือไม่มีชื่อ Schemaname) และส่งคืนข้อมูลด้านล่างหากมี schema.table อยู่:

the_name                object_id   the_schema  the_table       the_type
[Facts].[FactBackOrder] 758293761   Facts       FactBackOrder   Table

ฉันสร้างสคริปต์นี้เพื่อใช้ภายในสคริปต์อื่นทุกครั้งที่ฉันต้องการทดสอบว่ามีตารางหรือมุมมองอยู่หรือไม่และเมื่อใดให้รับ object_id เพื่อใช้สำหรับวัตถุประสงค์อื่น

มันทำให้เกิดข้อผิดพลาดเมื่อคุณผ่านสตริงว่างเปล่าชื่อสกีมาผิดหรือชื่อตารางที่ไม่ถูกต้อง

สิ่งนี้อาจอยู่ในขั้นตอนและส่งคืน -1 เช่น

ตัวอย่างเช่นฉันมีตารางชื่อ "Facts.FactBackOrder" ในหนึ่งในฐานข้อมูลคลังข้อมูลของฉัน

นี่คือวิธีที่ฉันได้รับ:

PRINT 'THE SERVER IS ' + @@SERVERNAME
--select db_name()
PRINT 'THE DATABASE IS ' + db_NAME() 
PRINT ''
GO

SET NOCOUNT ON
GO

--===================================================================================
-- @TableName is the parameter
-- the object we want to deal with (it might be an indexed view or a table)
-- the schema might or might not be specified
-- when not specified it is DBO
--===================================================================================

DECLARE @TableName SYSNAME

SELECT @TableName = 'Facts.FactBackOrder'
--===================================================================================
--===================================================================================
DECLARE @Schema SYSNAME
DECLARE @I INT
DECLARE @Z INT 

SELECT @TableName = LTRIM(RTRIM(@TableName))
SELECT @Z = LEN(@TableName)

IF (@Z = 0) BEGIN

            RAISERROR('Invalid @Tablename passed.',16,1)

END 

SELECT @I = CHARINDEX('.',@TableName )
--SELECT @TableName ,@I

IF @I > 0 BEGIN

        --===================================================================================
        -- a schema and table name have been passed
        -- example Facts.FactBackOrder 
        -- @Schema = Fact
        -- @TableName = FactBackOrder
        --===================================================================================

   SELECT @Schema    = SUBSTRING(@TABLENAME,1,@I-1)
   SELECT @TableName = SUBSTRING(@TABLENAME,@I+1,@Z-@I)



END
ELSE BEGIN

        --===================================================================================
        -- just a table name have been passed
        -- so the schema will be dbo
        -- example Orders
        -- @Schema = dbo
        -- @TableName = Orders
        --===================================================================================

   SELECT @Schema    = 'DBO'     


END

        --===================================================================================
        -- Check whether the @SchemaName is valid in the current database
        --===================================================================================

IF NOT EXISTS ( SELECT * FROM INFORMATION_SCHEMA.SCHEMATA K WHERE K.[SCHEMA_NAME] = @Schema ) BEGIN

            RAISERROR('Invalid Schema Name.',16,1)

END 

--SELECT @Schema  as [@Schema]
--      ,@TableName as [@TableName]


DECLARE @R1 TABLE (

   THE_NAME SYSNAME
  ,THE_SCHEMA SYSNAME
  ,THE_TABLE SYSNAME
  ,OBJECT_ID INT
  ,THE_TYPE SYSNAME
  ,PRIMARY KEY CLUSTERED (THE_SCHEMA,THE_NAME)

)

;WITH RADHE_01 AS (
SELECT QUOTENAME(SCHEMA_NAME(O.schema_id)) + '.' + QUOTENAME(O.NAME) AS [the_name]
      ,the_schema=SCHEMA_NAME(O.schema_id)
      ,the_table=O.NAME
      ,object_id =o.object_id 
      ,[the_type]= CASE WHEN O.TYPE = 'U' THEN 'Table' ELSE 'View' END 
from sys.objects O
where O.is_ms_shipped = 0
AND O.TYPE IN ('U','V')
)
INSERT INTO @R1 (
   THE_NAME 
  ,THE_SCHEMA 
  ,THE_TABLE 
  ,OBJECT_ID
  ,THE_TYPE 
)
SELECT  the_name
       ,the_schema
       ,the_table
       ,object_id
       ,the_type
FROM RADHE_01
WHERE the_schema = @Schema 
  AND the_table  = @TableName

IF (@@ROWCOUNT = 0) BEGIN 

             RAISERROR('Invalid Table Name.',16,1)

END 
ELSE BEGIN

    SELECT     THE_NAME 
              ,THE_SCHEMA 
              ,THE_TABLE 
              ,OBJECT_ID
              ,THE_TYPE 

    FROM @R1

END 

สคริปต์ของคุณมีข้อสมมติฐานมากมาย ตัวอย่างเช่นฉันสามารถเขียนชื่อตารางได้อย่างง่ายดายdbo.[hello.world ]และสคริปต์ไม่สามารถค้นหาได้ด้วยเหตุผลหลายประการ ที่กล่าวว่ามันไม่น่าจะมีใครอยากสร้างตารางเช่นนั้น แต่ก็ยัง อย่างไรก็ตามTHE_NAMEคอลัมน์ของคุณถูกกำหนดเป็นsysname', yet you try to squeeze 2 คอลัมน์ sysname` และจุด ( .) ทั้งหมดล้อมรอบด้วยวงเล็บเหลี่ยมในนั้น ... ที่หนึ่งถูกผูกไว้ที่จะล้มเหลวสักวันหนึ่ง!
deroby

@deroby ฉันเห็นด้วย sysname ไม่ใช่ชนิดข้อมูลที่ดีที่สุดที่จะใช้ แต่สคริปต์ทำงานมาเป็นเวลานานโดยไม่มีข้อผิดพลาดฉันจะใช้เวลากับมันเฉพาะเมื่อฉันพบสถานการณ์ที่สมเหตุสมผลที่ไม่สามารถใช้งานได้ ยิ่งไปกว่านั้นคุณจะต้องใช้รหัสนี้ปรับปรุงและโพสต์ที่นี่เป็นคำตอบและฉันจะทดสอบถ้ามันใช้งานได้ฉันจะอัปเกรดคำตอบของคุณ
Marcello Miorelli



2

สิ่งที่สำคัญที่จะรู้ว่าสำหรับใครที่ยังไม่ได้พบวิธีการแก้ปัญหาของพวกเขายัง: ! เซิร์ฟเวอร์ SQL = MYSQL ถ้าคุณต้องการที่จะทำกับMySQLมันค่อนข้างง่าย

    $sql = "SELECT 1 FROM `db_name`.`table_name` LIMIT 1;";
    $result = mysql_query($sql);
    if( $result == false )
        echo "table DOES NOT EXIST";
    else
        echo "table exists";

โพสต์สิ่งนี้ที่นี่เพราะเป็นที่นิยมที่สุดใน Google


4
-1 เนื่องจาก OP กำลังขอวิธีแก้ไขปัญหา SQL Server อย่างแม่นยำไม่ใช่ MySQL หนึ่งรายการ เขาเขียนเกี่ยวกับ MySQL เพราะเขารู้วิธีแก้ปัญหาของ DBMS นั้นและเขาต้องการผลลัพธ์เดียวกันบน SQL Server คำตอบของคุณไม่ได้เป็นเพียงแบบสอบถาม MySQL แต่เป็นรหัส PHP ที่ทำงานกับ MySQL
mordack550

1
@ mordack550 ฉันเห็นด้วยกับ Blauhirn เขาพูดถูก. นี่เป็นสิ่งที่ฮิตที่สุดใน Google สำหรับการค้นหาว่ามีตารางอยู่ใน SQL หรือไม่ ความตั้งใจของเขาดีและข้อมูลของเขาก็มีประโยชน์ +1
ทำเครื่องหมาย

เป็นเรื่องน่าเสียดายที่ Microsoft มีนิสัยพยายามที่จะโอบกอด / ขยาย / ดับมาตรฐานทั่วไปและรูปแบบเช่น SQL ฉันหวังว่าพวกเขาจะใช้ชื่อเซิร์ฟเวอร์ที่เหมาะสมกับ SQL server เพื่อให้ผู้คนสามารถระบุการอ้างอิงเฉพาะสำหรับผลิตภัณฑ์ของตนได้อย่างไม่น่าสงสัย
psaxton


2

คุณสามารถใช้สิ่งนี้:

     IF OBJECT_ID (N'dbo.T', N'U') IS NOT NULL 
        BEGIN 
            print 'deleted table';
            drop table t 
        END
     else 
        begin 
            print 'table not found' 
        end

 Create table t (id int identity(1,1) not null, name varchar(30) not null, lastname varchar(25) null)
 insert into t( name, lastname) values('john','doe');
 insert into t( name, lastname) values('rose',NULL);

 Select * from t
1   john    doe
2   rose    NULL

 -- clean
 drop table t


1

- - สร้างโพรซีเดอร์เพื่อตรวจสอบว่ามีตารางอยู่หรือไม่


DELIMITER $$

DROP PROCEDURE IF EXISTS `checkIfTableExists`;

CREATE PROCEDURE checkIfTableExists(
    IN databaseName CHAR(255),
    IN tableName CHAR(255),
    OUT boolExistsOrNot CHAR(40)
)

  BEGIN
      SELECT count(*) INTO boolExistsOrNot FROM information_schema.TABLES
      WHERE (TABLE_SCHEMA = databaseName)
      AND (TABLE_NAME = tableName);
  END $$

DELIMITER ;

- - วิธีใช้: ตรวจสอบว่ามีการย้ายข้อมูลตารางหรือไม่


 CALL checkIfTableExists('muDbName', 'migrations', @output);

1
IF EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE 
TABLE_CATALOG = 'Database Name' and
TABLE_NAME = 'Table Name' and 
TABLE_SCHEMA = 'Schema Name') -- Database and Schema name in where statement can be deleted

BEGIN
--TABLE EXISTS
END

ELSE BEGIN
--TABLE DOES NOT EXISTS
END

1

ฉันที่นี่การสร้างมุมมองที่เป็นตัวอย่างเช่น

เนื่องจากคำสั่ง ALTER / CREATE ไม่สามารถอยู่ในบล็อก BEGIN / END ได้ คุณต้องทดสอบการมีอยู่ของมันและทำการดรอปก่อนทำการสร้าง

IF Object_ID('TestView') IS NOT NULL
DROP VIEW TestView

GO

CREATE VIEW TestView
   as
   . . .

GO

หากคุณกังวลเกี่ยวกับการอนุญาตที่สูญหายคุณสามารถสคริปต์คำสั่ง GRANT ได้เช่นกันและเรียกใช้งานอีกครั้งในตอนท้าย

คุณสามารถตัดการสร้าง / ดัดแปลงเป็นสตริงและทำ EXEC ซึ่งอาจดูน่าเกลียดสำหรับมุมมองขนาดใหญ่

DECLARE @SQL as varchar(4000)

-- set to body of view
SET @SQL = 'SELECT X, Y, Z FROM TABLE' 

IF Object_ID('TestView') IS NULL
    SET @SQL = 'CREATE VIEW TestView AS ' + @SQL
ELSE    
    SET @SQL = 'ALTER VIEW TestView AS ' + @SQL

0

หากใครพยายามทำสิ่งเดียวกันนี้ใน linq ถึง sql (หรือโดยเฉพาะอย่างยิ่ง linqpad) ให้เปิดตัวเลือกเพื่อรวมตารางระบบและมุมมองและทำรหัสนี้:

let oSchema = sys.Schemas.FirstOrDefault(s=>s.Name==a.schema )
where oSchema !=null
let o=oSchema!=null?sys.Objects.FirstOrDefault (o => o.Name==a.item && o.Schema_id==oSchema.Schema_id):null
where o!=null

กำหนดว่าคุณมีวัตถุที่มีชื่อในคุณสมบัติที่เรียกว่ารายการและสคีมาในคุณสมบัติที่เรียกว่าสคีมาที่ชื่อตัวแปรแหล่งที่มาคือ a


0

หากนี่เป็นการอภิปรายที่ 'สุดยอด' ก็ควรสังเกตว่าสคริปต์ของ Larry Leonard สามารถสอบถามเซิร์ฟเวอร์ระยะไกลได้เช่นกันหากเซิร์ฟเวอร์มีการเชื่อมโยง

if exists (select * from REMOTE_SERVER.MyOtherDatabase.sys.tables where name = 'MyTable')
    print 'Exists'

อาจเหมาะสมกว่าที่จะเพิ่มสิ่งนี้เป็นความคิดเห็นในคำตอบของลีโอนาร์ดหรืออาจเป็นการแก้ไข?
EWit

0

ฉันมีปัญหาบางอย่างจากการเลือกจาก INFORMATIONAL_SCHEME และ OBJECT_ID ฉันไม่รู้ว่ามันเป็นปัญหาของไดรเวอร์ ODBC หรือเปล่า .. แบบสอบถามจากสตูดิโอจัดการ SQL ทั้งคู่ก็โอเค

นี่คือทางออก:

SELECT COUNT(*) FROM <yourTableNameHere>

ดังนั้นหากแบบสอบถามล้มเหลวอาจเป็นไปได้ว่าไม่มีตารางดังกล่าวในฐานข้อมูล (หรือคุณไม่มีสิทธิ์การเข้าถึง)

การตรวจสอบทำได้โดยการเปรียบเทียบค่า (จำนวนเต็มในกรณีของฉัน) ที่ส่งคืนโดยตัวจัดการ SQL ซึ่งจัดการกับไดรเวอร์ ODBC

if (sqlexec(conectionHandle, 'SELECT COUNT(*) FROM myTable') == -1) {
  // myTable doesn't exist..
}

ล้มเหลวกับสิ่งที่ส่งออก?
wscourge

@wscourge แบบสอบถาม SQL ล้มเหลวหรือบางสิ่งบางอย่างเหมือนกัน ฉันแค่ตรวจสอบค่าส่งคืนจากฟังก์ชั่นผู้ปฏิบัติการ
Michael Quad

เพิ่มไปยังคำตอบของคุณ
wscourge

0

มีอีกหนึ่งตัวเลือกในการตรวจสอบว่ามีตารางอยู่ในฐานข้อมูลหรือไม่

IF EXISTS(SELECT 1 FROM [change-to-your-database].SYS.TABLES WHERE NAME = 'change-to-your-table-name')
BEGIN
    -- do whatever you want
END

-1

เรียกใช้แบบสอบถามนี้เพื่อตรวจสอบว่าตารางที่มีอยู่ในฐานข้อมูล:

IF(SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'YourTableName') IS NOT NULL
PRINT 'Table Exists';

-6

พิจารณาในฐานข้อมูลเดียวที่คุณมีตาราง t1 คุณต้องการเรียกใช้สคริปต์บนฐานข้อมูลอื่นเช่น - ถ้ามี t1 อยู่แล้วอย่าทำอะไรเลยสร้าง t1 ในการทำสตูดิโอที่เปิดนี้และทำสิ่งต่อไปนี้:

คลิกขวาที่ t1 จากนั้นตารางสคริปต์เป็นจากนั้น DROP และ Create To จากนั้นเลือก New Query Editor

คุณจะพบคำค้นหาที่คุณต้องการ แต่ก่อนที่จะเรียกใช้งานสคริปต์นั้นอย่าลืมที่จะใส่ความคิดเห็นของคำสั่งดร็อปในแบบสอบถามเนื่องจากคุณไม่ต้องการสร้างใหม่หากมีอยู่แล้ว

ขอบคุณ


ใน SSMS 2012 จะไม่ทำการตรวจสอบที่มีอยู่อีกต่อไปถ้าเคยทำมาแล้ว (ฉันจำไม่ได้ว่าเวอร์ชันก่อนหน้านี้สร้างสคริปต์ด้านบน) บางทีคุณอาจเข้าใจผิดกับวิธีที่เครื่องมือ db อื่น ๆ เป็นวัตถุตารางสคริปต์?
Ivaylo Slavov

SSMS จะทำการตรวจสอบถ้ามีอยู่ถ้าคุณถามมัน เครื่องมือ> ตัวเลือก> SQL Server Object Explorer> การเขียนสคริปต์> "ตัวเลือกการเขียนสคริปต์วัตถุ": "ตรวจสอบการมีอยู่ของวัตถุ" = True
Seann Alexander
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.