首页 文章

检查SQL Server中是否存在表

提问于
浏览
925

我希望这是关于如何使用SQL语句检查SQL Server 2000/2005中是否存在表的最终讨论 .

当谷歌找到答案时,你会得到很多不同的答案 . 这样做是否有正式/后向和前向兼容的方式?

这有两种可能的方法 . 这两者中哪一个是标准/最佳方式?

第一种方式:

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 回答

  • 10

    对于像这样的查询,最好使用 INFORMATION_SCHEMA 视图 . 这些视图(大多数)是许多不同数据库的标准视图,很少从版本更改为版本 .

    要检查表是否存在,请使用:

    IF (EXISTS (SELECT * 
                     FROM INFORMATION_SCHEMA.TABLES 
                     WHERE TABLE_SCHEMA = 'TheSchema' 
                     AND  TABLE_NAME = 'TheTable'))
    BEGIN
        --Do Stuff
    END
    
  • 4
    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 .

  • 97

    请看下面的方法,

    Approach 1: Using INFORMATION_SCHEMA.TABLES view

    我们可以编写如下的查询来检查当前数据库中是否存在Customers表 .

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

    Approach 2: Using OBJECT_ID() function

    我们可以使用如下的OBJECT_ID()函数来检查当前数据库中是否存在Customers表 .

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

    Approach 3: Using sys.Objects Catalog View

    我们可以使用Sys.Objects目录视图来检查Table的存在,如下所示:

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

    Approach 4: Using sys.Tables Catalog View

    我们可以使用Sys.Tables目录视图来检查Table的存在,如下所示:

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

    Approach 5: Avoid Using sys.sysobjects System table

    我们应该避免直接使用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/

  • 31

    如果这是“终极”讨论,那么应该注意的是,如果服务器是链接的,Larry Leonard的脚本也可以查询远程服务器 .

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

    使用信息模式是SQL标准的方法,所以它应该被支持它的所有数据库使用 .

  • 0

    对于尚未找到解决方案的人来说,重要的是要知道: 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";
    

    在此发布此消息是因为它是谷歌的热门话题 .

  • -5
    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
    
  • 1

    在一个数据库中考虑你有一个表t1 . 你想在其他数据库上运行脚本 - 如果t1存在则不做任何其他创建t1 . 要做到这一点,打开visual studio并执行以下操作:

    右键单击t1,然后单击脚本表,然后单击DROP和Create To,再单击New Query Editor

    你会找到你想要的查询 . 但在执行该脚本之前,不要忘记在查询中注释掉drop语句,因为如果已经存在,则不想创建新语句 .

    谢谢

  • 1119

    另请注意,如果出于任何原因需要检查临时表,可以执行以下操作:

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

    只要我记得,我们总是使用 OBJECT_ID 样式

    IF OBJECT_ID('*objectName*', 'U') IS NOT NULL
    
  • 2
    select name from SysObjects where xType='U' and name like '%xxx%' order by name
    
  • 233

    SQL Server 2000 你可以尝试:

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

    只是想提一下使用 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 将允许您开箱即用 . EX-

    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 包装器相同的操作 .

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

  • 193

    如果有人试图在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

  • 19

    如果您需要在不同的数据库上工作:

    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
    
  • 16
    IF EXISTS 
    (
        SELECT  * 
    
        FROM    INFORMATION_SCHEMA.TABLES 
    
        WHERE   TABLE_SCHEMA = 'PutSchemaHere'     
                AND  
                TABLE_NAME   = 'PutTableNameHere'
    )
    
  • 8

    IF OBJECT_ID(N'dbo.T',N'U')不是NULL
    开始
    打印'删除表';
    下降表t
    结束
    其他
    开始
    打印'找不到表'
    结束

    创建表t(id int identity(1,1)not null,name varchar(30)not null,lastname varchar(25)null)
    插入t(name,lastname)值('john','doe');
    插入t(name,lastname)值('rose',NULL);

    从t中选择*
    1约翰
    2玫瑰NULL

    • 干净
      下降表t
  • 0

    为了开发人员和其他DBA的利益,只需添加此处

    接收@Tablename作为参数的脚本

    (如果schema.table存在,则可能包含或不包含schemaname)并返回以下信息:

    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
    
  • 3

    在不同的数据库上查找表:

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

      • 创建过程以检查表是否存在

    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);
    
  • 0
    IF OBJECT_ID('mytablename') IS NOT NULL
    
  • 3

    我知道这是一个老问题,但如果你打算经常打电话,我发现了这种可能性 .

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

相关问题