当表有0行时如何检查数据库表是不是存在?

Posted

技术标签:

【中文标题】当表有0行时如何检查数据库表是不是存在?【英文标题】:How to check if database table exists when the table has 0 rows?当表有0行时如何检查数据库表是否存在? 【发布时间】:2019-01-28 14:04:24 【问题描述】:

编辑:很抱歉浪费大家的时间,下面的代码表明我刚刚忘记了 C_TABLE 上的“C”,在更正后可以正常工作。

如果表存在于数据库中,则在以下代码中“存在”应该 == 1。但是,它为我返回 0,即使该表存在于数据库中。我不确定为什么会这样?

谢谢:

foreach (var row in calcSched)
            
                var dif3 = new DataInterfaceFactory(DatabaseTypes.SqlServer, row.DatabaseName, row.ServerName);

                using (DataReader dr2 = dif3.GetDataReader())
                
                    dr2.ExecuteReader("SELECT COUNT(1) AS TABLECOUNT2 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'C_TABLE'");
                    var exists = Convert.ToInt32(dr2["TABLECOUNT2"]);
                    CommandExecutor CE = dif3.GetCommandExecutor();

                    try
                    
                        if (exists == 0)
                        
                            string sql = "CREATE TABLE dbo.C_TABLE(COLUMN_UID INT, KIP INT, SD_DATE DATE, ST INT, CS_DATE DATE, CE_DATE DATE, SM CHAR(100), PRG CHAR(20)";
                            CE.ExecuteNonQuery(sql);
                        
                    
                    catch (Exception ex)
                    
                        Console.WriteLine("Error: could not create C_TABLE");
                    
                
            

【问题讨论】:

“我的理解是至少需要一行才能返回 1” - 我不会这么认为,不;只要它存在,它就应该适用于空表;你测试过这个假设吗? (我刚刚做了:效果很好) 空行集上的COUNT(..) 始终存在并且为0(嗯,很明显)。 ExecuteScalar 就是你所需要的。 @JeroenMostert 是的,但是它使用异常作为“不,它不存在”的情况 - 通常不是一个好主意,但是......它会起作用,我猜 @LasseVågsætherKarlsen 抱歉,我完全错了。我已经编辑了这个问题。因为表存在,它应该返回 1,而不是 0。目前,由于它返回 0,并且由于它已经存在而无法创建表,所以它正在抛出错误。 如果您发布的代码准确无误,请检查DataReader 的实际含义以及ExecuteReader 应该做什么。看起来这不是使用 ADO.NET 标准类,而是使用一些自定义层,它可以对您的查询做各种有趣的事情——它可以以人类未知的方式包装或破坏它。您也可能只是转到错误的服务器或数据库,再次基于我们在这里看不到的一些动态配置。 【参考方案1】:

您正在使用ExecuteReader,然后您尝试访问其中的数据,而无需先执行dr2.Read()

【讨论】:

好眼睛!但是,简单地切换到ExecuteScalar 可能是务实的(请参阅我对问题的评论),以避免一些其他相关问题【参考方案2】:

据我所知,这是 MS SQL Server。可以直接查询sys.tables。即:

select case when exists ( select  *
                from    sys.tables
                where   [name] = 'YourTableName'
                        and is_ms_shipped = 0 )  then 1 else 0 end;

您也可以在连接上直接使用 GetSchema 进行查询。即:

void Main()

  string strCon =
      @"server=.\sqlexpress;database=Northwind;Trusted_connection=yes";
  DataTable schemaInfo;    
  string[] restrictions = "Northwind",null,null,"BASE TABLE";

  using( SqlConnection con = new SqlConnection(strCon))
  
   con.Open();
   schemaInfo = con.GetSchema("Tables", restrictions );
   con.Close();
  
  // schemaInfo datatable contains all tables

PS:您误导人们,好像这是在 MS SQL Server 中检查表是否存在的方式,从而导致一些人对正确的方式投反对票。

【讨论】:

不是我的否决票,但我预计它被否决的原因是因为 特定查询 不是这里的问题 - 查询已经显示很好;因此,我们可以合理地假设更改查询实际上无济于事 @MarcGravell,我没有更改查询。简单地展示正确的方法。为什么他要尝试使用错误的方式? 这种方式并不比查询信息模式更“正确”;是的,你完全改变了查询 @MarcGravell,这是正确的做法。喜欢与否。 (上面有人已经提供了链接)information_schema 不可靠。 我可以看到我们不会就这一点达成一致,但是:任何一个都可以很好在这里(好像我们不需要只存在于表,而不是视图);查询不是问题,因此提出不同的查询是没有帮助的。我肯定会说使用 GetSchema 是个坏主意,不过 - 对于这种情况来说完全是矫枉过正,而且使用 API 实在是可怕,尤其是当我们只想知道一件很简单的事(存在)

以上是关于当表有0行时如何检查数据库表是不是存在?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:当表有两个外键时,为具有关系的数据库表播种

更新informix中的行时如何修复错误-245

检查用户名是不是存在于数据库中

MySQL 从表中获取数据并检查表行中是不是存在用户 ID

雪花任务条件:当表有数据时

当表没有行时,将表的可见性设置为 false(在报告服务中)