Проверьте, существует ли таблица в SQL Server



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


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

1358   22  

22 ответов:

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

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

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

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

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

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

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

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

подход 1: Использование INFORMATION_SCHEMA.Просмотр таблиц

мы можем написать запрос, как показано ниже, чтобы проверить, существует ли таблица Customers в текущей базе данных.

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

подход 2: Использование функции OBJECT_ID ()

мы можем использовать функцию OBJECT_ID (), как показано ниже, чтобы проверить, существует ли таблица Customers в текущей базе данных.

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

Подход 3: Использование системный.Представление Каталога Объектов

мы можем использовать Sys.Просмотр каталога объектов для проверки существования таблицы, как показано ниже:

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.Просмотр Каталога Таблиц

мы можем использовать Sys.Просмотр каталога таблиц для проверки существования таблицы, как показано ниже:

 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.объекты/системы.таблицы вместо 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/

Поиск таблицы в другой базе данных:

if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
    print 'Exists'
IF OBJECT_ID('mytablename') IS NOT NULL 

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

начиная с 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/

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

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.

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

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

Я знаю, это старый вопрос, но я нашел такую возможность, если вы планируете звонить часто.

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

просто добавляя здесь, в интересах разработчиков и коллег DBAs

скрипт, который получает @Tablename в качестве параметра

(который может содержать или не содержать имя схемы) и возвращает информацию ниже, если схема.существует таблица:

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

Я создал этот скрипт для использования внутри других скриптов каждый раз, когда мне нужно проверить, существует ли таблица или представление, и когда это происходит, получить его object_id для использования в других целях.

It вызывает ошибку, если вы передали пустую строку, неправильное имя схемы или неправильное имя таблицы.

это может быть внутри процедуры и возвращают -1 например.

например, у меня есть таблица под названием "Факты.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 

In SQL Server 2000 можно попробовать:

IF EXISTS(SELECT 1 FROM sysobjects WHERE type = 'U' and name = 'MYTABLENAME')
BEGIN
   SELECT 1 AS 'res' 
END
IF EXISTS 
(
    SELECT  * 

    FROM    INFORMATION_SCHEMA.TABLES 

    WHERE   TABLE_SCHEMA = 'PutSchemaHere'     
            AND  
            TABLE_NAME   = 'PutTableNameHere'
)
    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

что важно знать для тех, кто еще не нашел своего решения: SQL server != 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.

select name from SysObjects where xType='U' and name like '%xxx%' order by name

Если кто-то пытается сделать то же самое в linq to 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

учитывая, что у вас есть объект с именем в свойстве с именем item и схема в свойстве с именем schema, где имя исходной переменной a

Если это должно быть "окончательное" обсуждение, то следует отметить, что сценарий Ларри Леонарда может запрашивать удаленный сервер, а также если серверы связаны.

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

-- -- создать процедуру, чтобы проверить, существует ли таблица


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);
IF EXISTS (   SELECT * FROM   dbo.sysobjects WHERE  id = OBJECT_ID(N'dbo.TableName') AND OBJECTPROPERTY(id, N'IsUserTable') = 1 )
BEGIN
  SELECT * FROM dbo.TableName;
END
GO

рассмотрим в одной базе данных у вас есть таблица t1. вы хотите запустить скрипт на другой базе данных, например - если t1 существует, то больше ничего не создавайте t1. Для этого откройте visual studio и выполните следующие действия:

щелкните правой кнопкой мыши на t1, затем Script table as, затем DROP и Create To, а затем новый редактор запросов

вы найдете нужный запрос. Но перед выполнением этого скрипта не забудьте закомментировать оператор Drop в запросе как вы не хотите создавать новый, если есть уже один.

спасибо

Comments

    Ничего не найдено.