代码之家  ›  专栏  ›  技术社区  ›  Carra

检查SQL表是否存在

  •  38
  • Carra  · 技术社区  · 17 年前

    我想到了:

       bool exists;
       const string sqlStatement = @"SELECT COUNT(*) FROM my_table";
    
       try
        {
           using (OdbcCommand cmd = new OdbcCommand(sqlStatement, myOdbcConnection))
           {
                cmd.ExecuteScalar();
                exists = true;
           }
        }
        catch
        {
            exists = false;
        }
    

    有更好的方法吗?当与数据库的连接失败时,此方法将不起作用。我已经找到了Sybase、SQL server和Oracle的方法,但没有任何方法可以适用于所有数据库。

    9 回复  |  直到 15 年前
        1
  •  68
  •   Matt Mitchell    16 年前
    bool exists;
    
    try
    {
        // ANSI SQL way.  Works in PostgreSQL, MSSQL, MySQL.  
        var cmd = new OdbcCommand(
          "select case when exists((select * from information_schema.tables where table_name = '" + tableName + "')) then 1 else 0 end");
    
        exists = (int)cmd.ExecuteScalar() == 1;
    }
    catch
    {
        try
        {
            // Other RDBMS.  Graceful degradation
            exists = true;
            var cmdOthers = new OdbcCommand("select 1 from " + tableName + " where 1 = 0");
            cmdOthers.ExecuteNonQuery();
        }
        catch
        {
            exists = false;
        }
    }
    
        2
  •  11
  •   ConcernedOfTunbridgeWells    17 年前

    如果您试图实现数据库独立性,则必须假定最低标准。美国国家标准协会 INFORMATION_SCHEMA

    select count (*) 
      from information_schema.tables 
     where table_name = 'foobar'
    

    鉴于您正在使用ODBC,还可以使用各种 ODBC API calls 也要检索此元数据。

    记住,可移植性等同于 write-once test anywhere 因此,您仍然需要在您打算支持的每个平台上测试应用程序。这意味着,由于您只有这么多用于测试的资源,您天生就被限制在有限数量的可能的数据库平台上。

    结果是,您需要为您的应用程序找到一个最低的公分母(这比寻找SQL要困难得多),或者构建一个平台相关的部分,其中非可移植函数可以在每个平台的基础上插入。

        3
  •  10
  •   Frederik Gheysels    17 年前

    但是,为什么要使用特定的查询来执行此操作? 你不能把实现从你想做的事情中抽象出来吗? 然后,对于要支持的每个DBMS,创建一个实现该接口的类,并在TableExists方法中为该DBMS编写特定的逻辑。

    在应用程序中,您可以使用一个工厂类为给定上下文创建正确的实现,然后您只需调用TableExists方法。

    例如:

    IMyInterface foo = MyFactory.CreateMyInterface (SupportedDbms.SqlServer);
    
    if( foo.TableExists ("mytable") )
    ...
    

    我想我应该这样做。

        4
  •  4
  •   Sebastian Dietz    17 年前

    但是,如果确实必须使用示例中的异常处理来执行检查,则应使用比计数(*)更有效的以下查询,因为数据库没有实际的选择工作要做:

    SELECT 1 FROM my_table WHERE 1=2
    
        5
  •  4
  •   Imran Ali Khan    12 年前

    select count(x) from xxxxxx 因为DBMS实际上将继续并完成这项工作,这对于一个大表来说可能需要一些时间。

    而是 A. select * from mysterytable

        6
  •  2
  •   abatishchev Karl Johan    17 年前

        7
  •  2
  •   Arvo Bowen    9 年前

    以下内容对我很有用。。。

    private bool TableExists(SqlConnection conn, string database, string name)
    {
        string strCmd = null;
        SqlCommand sqlCmd = null;
    
        try
        {
            strCmd = "select case when exists((select '['+SCHEMA_NAME(schema_id)+'].['+name+']' As name FROM [" + database + "].sys.tables WHERE name = '" + name + "')) then 1 else 0 end";
            sqlCmd = new SqlCommand(strCmd, conn);
    
            return (int)sqlCmd.ExecuteScalar() == 1;
        }
        catch { return false; }
    }
    
        8
  •  0
  •   Andreas Johansson    9 年前

    如果您想避免使用try-catch解决方案,我建议使用sys.tables使用这种方法

    private bool IsTableExisting(string table)
        {
            string command = $"select * from sys.tables";
            using (SqlConnection con = new SqlConnection(Constr))
            using (SqlCommand com = new SqlCommand(command, con))
            {
                SqlDataReader reader = com.ExecuteReader();
                while (reader.Read())
                {
                    if (reader.GetString(0).ToLower() == table.ToLower())
                        return true;
                }
                reader.Close();
            }
            return false;
        }
    
        9
  •  0
  •   Mustafa Bükülmez    8 年前

    use YOUR_DATABASE --OPTIONAL
    SELECT count(*) as Exist from INFORMATION_SCHEMA.TABLES where table_name = 'YOUR_TABLE_NAME'
    

    如果答案是1,则有一个表。 如果答案为0,则没有表。