如何从从GetSchema获得的表中获取第一列

本文关键字:一列 获取 GetSchema | 更新日期: 2023-09-27 17:53:11

首先,我为标题道歉。如果没有更多的解释,我认为它不能准确地描述我正在做的事情。

我使用ODBCConnectionGetSchema()方法来获取数据库模式中的表列表。这很好。但是,我有一个新的需求,我需要获得第一个列名或主键列的名称。我想知道如何同时获得这两个字段,但如果必须选择,我将选择第一个列名。

下面是我用来获取表列表的代码:
private List<string> GetSortedSchemaList(string strConnection, string strSchema)
{
    List<string> lstSortedSchemaList = new List<string>();
    using (OdbcConnection odbcCon = new OdbcConnection(strConnection))
    {
        try
        {
            odbcCon.Open();
            using (DataTable tableSchema = odbcCon.GetSchema("TABLES"))
            {                       
                OdbcCommand odbcCmd = new OdbcCommand();
                foreach (DataRow row in tableSchema.Rows)
                {
                    string tableSchem = row["TABLE_SCHEM"].ToString();
                    if (strSchema != "ABC")
                    {
                        lstSortedSchemaList.Add(row["TABLE_SCHEM"] + "." + row["TABLE_NAME"]);
                    }
                }
            }
            odbcCon.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString() + "'nFailed to connect to data source");
        }
    }

然后在下面的方法中调用前面的方法:

private void GetTableCounts
    (string strConnection, string strSchemaName, int intTotalTables, BackgroundWorker worker, DoWorkEventArgs e)
{
    List<string> lstSchema = new List<string>(GetSortedSchemaList(strConnection, strSchemaName));
    using (OdbcConnection odbcCon = new OdbcConnection(strConnection))
    {
        try
        {
            odbcCon.Open();
            if (strSchemaName == "ABC")
            {
                AppendTextBoxPM(strSchemaName + " tables processing...'r'n");
            }
            OdbcCommand odbcCmd = new OdbcCommand();
            foreach (var i in lstSchema)
            {
                var item = i;
                Debug.Write((lstSchema.IndexOf(item) + 1) + ". Item = " + item + "'r'n");
                odbcCmd.CommandText = "SELECT Count(ID) FROM " + item;
                odbcCmd.Connection = odbcCon;
                if (strSchemaName == "ABC")
                {
                    AppendTextBoxPM(item + " Count = " + Convert.ToInt32(odbcCmd.ExecuteScalar()) + "'r'n");
                }
                int intPercentComplete = (int)((float)(lstSchema.IndexOf(item) + 1) / (float)intTotalTables * 100);
                Thread.Sleep(100);
                worker.ReportProgress(intPercentComplete);
                ModifyLabel(" (" + (lstSchema.IndexOf(item) + 1) + " out of " + intTotalTables + " processed)");
            }
            odbcCmd.Dispose();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString() + "'nFailed to connect to data source");
            return;
        }
    }
}

因此,我可以获得表的列表,并且我能够运行ODBC命令来查询这些表。然而,我使用的查询,SELECT Count(ID) FROM Item,不会工作,因为不是每个表都有一个名为ID的字段。这就是抢占第一个字段的原因。我不能使用SELECT Count(*) FROM Item,因为我使用的数据库允许计算字段,执行Count(*)导致查询/查询需要很长时间才能完成,因为它正在计算所有的计算(或者我的供应商告诉我)。

无论如何,我不太明白GetSchema()方法是如何工作的,即使在彻底阅读和审查了每一个相关的SO帖子,谷歌搜索结果等之后。我知道我必须钻取GetSchema()来获得列名,但我不确定如何在我的情况下应用它,因为我所看到的所有示例都使用foreach语句/循环一次显示所有列。

最重要的是,当我将表添加到lstSortedSchemaList列表时,我还希望获得该表的第一个列名。它可以在第一个代码片段中获得,并连接到我要添加到列表中的项(并且我可以解析它),或者在第二个代码片段中获得,如果这样更优雅的话。

我所尝试的一切都遵循了我在互联网上发现的例子,只是输出"TABLE_CAT"作为列名。我基本上将tableSchema数据表发送到另一个方法,并使用另一个foreach循环与DataRow和嵌入式foreachDataColumn,但这并没有像我想象的那样工作。

谢谢你的帮助

如何从从GetSchema获得的表中获取第一列

有了表名之后,可以再次调用GetSchema方法来检索特定表的列名,按字段ORDINAL_POSITION

排序
DataTable schemaCols = con.GetSchema("Columns");
DataRow[] rows = schemaCols.Select("TABLE_NAME='" + tableName + "'", "ORDINAL_POSITION");
string firstCol = rows[0]["COLUMN_NAME"].ToString();
Console.WriteLine(firstCol);