Проверьте, существует ли таблица в 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 ]

8 голосов
/ 21 января 2011

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

create procedure Table_Exists
@tbl varchar(50)
as
return (select count(*) from sysobjects where type = 'U' and name = @tbl)
go
5 голосов
/ 23 января 2015

Просто добавив сюда, в интересах разработчиков и коллег-администраторов баз данных

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

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

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 
4 голосов
/ 16 апреля 2015

В SQL Server 2000 вы можете попробовать:

IF EXISTS(SELECT 1 FROM sysobjects WHERE type = 'U' and name = 'MYTABLENAME')
BEGIN
   SELECT 1 AS 'res' 
END
3 голосов
/ 18 ноября 2014
    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
3 голосов
/ 24 октября 2013
IF EXISTS 
(
    SELECT  * 

    FROM    INFORMATION_SCHEMA.TABLES 

    WHERE   TABLE_SCHEMA = 'PutSchemaHere'     
            AND  
            TABLE_NAME   = 'PutTableNameHere'
)
2 голосов
/ 23 июля 2014

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

1 голос
/ 10 февраля 2014
select name from SysObjects where xType='U' and name like '%xxx%' order by name
1 голос
/ 19 июня 2018
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
0 голосов
/ 29 мая 2019

Запустите этот запрос, чтобы проверить, существует ли таблица в базе данных:

IF(SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'YourTableName') IS NOT NULL
PRINT 'Table Exists';
0 голосов
/ 22 марта 2019

У меня были некоторые проблемы с выбором из INFORMATIONAL_SCHEME и OBJECT_ID. Я не знаю, проблема ли это в драйвере ODBC или что-то в этом роде. Запросы из студии управления SQL, оба были в порядке.

Вот решение:

SELECT COUNT(*) FROM <yourTableNameHere>

Итак, если запрос не выполнен, вероятно, в базе данных нет такой таблицы (или у вас нет прав доступа к ней).

Проверка выполняется путем сравнения значения (целое число в моем случае), возвращаемого исполнителем SQL, который работает с драйвером ODBC.

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