【问题标题】: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 标准类,而是使用一些自定义层,它可以对您的查询做各种有趣的事情——它可以以人类未知的方式包装或破坏它。您也可能只是转到错误的服务器或数据库,再次基于我们在这里看不到的一些动态配置。

标签: c# sql-server database datareader


【解决方案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 实在是可怕,尤其是当我们只想知道一件很简单的事(存在)
猜你喜欢
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 2012-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
相关资源
最近更新 更多