Проверьте, существует ли таблица в 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%';
заявление. Я ищу что-то подобное.
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'
просто хотел упомянуть одну ситуацию, где, вероятно, было бы немного проще использовать
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 строке кода.
использование информационной схемы является стандартным способом 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.
Если кто-то пытается сделать то же самое в 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