获取DataTable列字符表示的最大长度

时间:2014-04-01 17:43:07

标签: c# ms-access

我在Access数据库中有一个表,我试图使用C#来获取列名和每列的字符串表示的最大长度。也就是说,如果表格如下所示:

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

如果ID和SysBP列是数字列,我想要一个包含以下信息的DataTable对象:

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

我有一个与数据库和两个DataTable对象的OLEDB连接,一个用于表模式,另一个用于实际表。

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

    ...???
}

任何人都可以提供有关如何计算该字段的任何见解吗?

2 个答案:

答案 0 :(得分:1)

Access在Sql Server中没有像sys.columns这样的好表,所以你必须手动实现它。

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;
            }
        }

    }
}

答案 1 :(得分:0)

这就是我最终这样做的方式。对我来说最有意义。在获取长度之前,将数值转换为字符串。谢谢@Brad的回答。

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;
}