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

时间:2014-03-25 22:56:39

标签: c# .net-4.0 odbc

首先,我为标题道歉。我不认为它准确地描述了我在没有更多解释的情况下要做的事情。

我正在使用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帖子,Google搜索结果等后的工作原理。我明白我必须深入研究{{1}获取列名,但我不知道如何在我的情况下应用它,因为我看到的所有示例都使用GetSchema()语句/循环一次显示所有列。

从底线开始,当我将表添加到foreach列表时,我还想获得该表的第一个列名。它可以在第一个代码片段中获得,并连接到我正在添加到列表中的项目(我可以解析它),或者在第二个代码片段中获得,如果它更优雅。

我尝试的所有内容都遵循我在Inter-webs中找到的示例,只输出“TABLE_CAT”作为列名。我基本上将lstSortedSchemaList数据表发送到另一个方法,并使用另一个tableSchema循环,其中foreach和嵌入式DataRow的{​​{1}},但没有像我想的那样工作。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

获得表的名称之后,您可以再次调用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);