Get maximum length of DataTable column character representation

夙愿已清 提交于 2019-12-25 02:19:47

问题


I have a table in an Access database and I'm trying to use C# to get the column names and the maximum length of the string representations of each column. That is, if the table looks like this:

Name     ID  SysBP
-------------------
Jerry  1234  108.1
Tim     123  140.6
Marge     6   99.0

Where the ID and SysBP columns are numeric columns, I want a DataTable object that contains the following information:

ColumnName  MaxCharLen
----------------------
Name        5
ID          4
SysBP       4

I have an OLEDB connection to the database and two DataTable objects, one for the table schema and one for the actual table.

public DataTable GetMetadata(string tableName)
{
    // At this point the _oleConnection object exists and is open...
    OleDbCommand selectTable = new OleDbCommand("SELECT * FROM [" + tableName + "]",
        _oleConnection);

    OleDbDataReader oleReader = selectTable.ExecuteReader();

    // Column names from table schema
    DataTable schemaTable = oleReader.GetSchemaTable();
    schemaTables.Columns.Add("MaxCharLen", typeof(int));

    // Import full Access table as DataTable
    DataTable tableRecords = new DataTable();
    tableRecords.Load(oleReader);

    // Get maximum length of string representations by column
    // Populate MaxCharLen with that information

    ...???
}

Can anyone provide any insight on how to go about calculating that field?


回答1:


Access doesn't have any nice table like sys.columns in Sql Server so you'll have to, to my knowledge, manually make it happen.

private static DataTable GetMetaDataSummary(string tableName)
{
    using (OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\bradley_handziuk\Documents\Database4.accdb;Persist Security Info=False;"))
    {
        var cmdText = String.Format("Select * from [{0}]", tableName);
        List<string> queryBuilder = new List<string>();
        conn.Open();
        using (OleDbCommand cmd = new OleDbCommand(cmdText, conn))
        {
            using (OleDbDataReader oleReader = cmd.ExecuteReader())
            {
                for (int c = 0; c < oleReader.FieldCount; c++)
                {
                    queryBuilder.Add(String.Format("Select '{0}' as ColumnName, max(len([{0}])) as MaxCharLength from [{1}]", oleReader.GetName(c), tableName));
                }
            }
        }
        var cmdText2 = String.Join(" Union All ", queryBuilder);
        using (OleDbCommand cmd = new OleDbCommand(cmdText2, conn))
        {
            using (OleDbDataReader oleReader = cmd.ExecuteReader())
            {
                DataTable tableRecords = new DataTable();
                tableRecords.Load(oleReader);
                return tableRecords;
            }
        }

    }
}



回答2:


This is how I ended up doing it. Made the most sense to me. The numeric values are cast to strings before getting the lengths. Thanks @Brad for your answer.

public static T ConvertFromDBVal<T>(object obj)
{
    if (obj == null || Convert.IsDBNull(obj))
        return default(T);
    else
        return (T)obj;
}

public DataTable GetMetadata(string tableName)
{
    // Again, connection open at this point

    OleDbCommand selectTable = new OleDbCommand("SELECT * FROM [" +
        tableName + "]", _oleConnection);

    OleDbDataReader oleReader = selectTable.ExecuteReader();

    DataTable schemaTable = oleReader.GetSchemaTable().Copy();
    schemaTable.Columns.Add("_maxCharLength", typeof(int));

    foreach (DataRow schemaRow in schemaTable.Rows)
    {
        OleDbCommand getMax = new OleDbCommand();
        getMax.Connection = _oleConnection;

        if (schemaRow.Field<Type>("DataType") == typeof(string))
            getMax.CommandText = "SELECT MAX(LEN(" +
                schemaRow.Field<string>("ColumnName") + ")) FROM " +
                tableName;
        else
            getMax.CommandText = "SELECT MAX(LEN(STR(" +
                schemaRow.Field<string>("ColumnName") + "))) FROM " +
                tableName;

        int maxCharLength = ConvertFromDBVal<int>(getMax.ExecuteScalar());

        schemaRow.SetField("_maxCharLength", maxCharLength);

        getMax.Dispose();
        getMax = null;
    }

    ...

    return schemaTable;
}


来源:https://stackoverflow.com/questions/22793072/get-maximum-length-of-datatable-column-character-representation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!