Проверьте, существует ли таблица в SQL Server - PullRequest
994 голосов
/ 03 октября 2008

Мне бы хотелось, чтобы это было окончательное обсуждение того, как проверить, существует ли таблица в 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%'; 

заявление. Я ищу что-то похожее.

Ответы [ 24 ]

1201 голосов
/ 03 октября 2008

Для подобных запросов всегда лучше использовать INFORMATION_SCHEMA представление. Эти представления (в основном) являются стандартными для многих различных баз данных и редко меняются от версии к версии.

Чтобы проверить, существует ли таблица, используйте:

IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'TheSchema' 
                 AND  TABLE_NAME = 'TheTable'))
BEGIN
    --Do Stuff
END
249 голосов
/ 28 января 2010

Также обратите внимание, что если по какой-либо причине вам нужно проверить временную таблицу, вы можете сделать это:

if OBJECT_ID('tempdb..#test') is not null
 --- temp table exists
211 голосов
/ 03 октября 2008

Мы всегда используем стиль OBJECT_ID, насколько я помню

IF OBJECT_ID('*objectName*', 'U') IS NOT NULL 
109 голосов
/ 22 декабря 2014

Пожалуйста, смотрите ниже подходы,

Подход 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 Catalog View

Мы можем использовать представление каталога 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 напрямую, прямой доступ к ней будет устаревшим в некоторых будущих версиях 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/

34 голосов
/ 15 марта 2012

Ищем таблицу в другой базе данных:

if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
    print 'Exists'
23 голосов
/ 22 июня 2016

Просто хотел бы упомянуть одну ситуацию, когда было бы немного проще использовать метод OBJECT_ID. INFORMATION_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 Редактировать :

Начиная с 2016 года, Microsoft упростила возможность проверки несуществующих объектов перед удалением, добавив ключевые слова if exists в операторы drop. Например,

drop table if exists mytablename

будет делать то же самое, что и OBJECT_ID / INFORMATION_SCHEMA упаковщики, в 1 строке кода.

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

20 голосов
/ 22 ноября 2013
IF OBJECT_ID('mytablename') IS NOT NULL 
15 голосов
/ 03 октября 2008

Использование информационной схемы - это стандартный способ SQL, поэтому она должна использоваться всеми базами данных, которые ее поддерживают.

10 голосов
/ 07 апреля 2011
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.

10 голосов
/ 21 октября 2009

Если вам нужно работать с разными базами данных:

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
...