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

Posted

技术标签:

【中文标题】获取 DataTable 列字符表示的最大长度【英文标题】:Get maximum length of DataTable column character representation 【发布时间】:2014-04-01 17:43:07 【问题描述】:

我在 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

我有一个到数据库的 OLEDB 连接和两个 DataTable 对象,一个用于表架构,一个用于实际表。

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

    ...???

谁能提供有关如何计算该字段的任何见解?

【问题讨论】:

【参考方案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;
            
        

    

【讨论】:

在这种情况下,像sys.columns 这样的唯一有用信息是列名,在我的例子中,它直接来自oleReader.GetSchemaTable() 是的,在这种情况下是真的。如果您打算在服务器上执行所有这些操作,您将使用 sys.columns 而不是数据读取器来进行动态查询。【参考方案2】:

这就是我最终做到的方式。对我来说最有意义。在获取长度之前将数值转换为字符串。感谢@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;

【讨论】:

以上是关于获取 DataTable 列字符表示的最大长度的主要内容,如果未能解决你的问题,请参考以下文章

DataTables 循环遍历表并删除特定列中包含特定字符串的所有行

DataRow数组如何获得行数

CHAR 和 VARCHAR

剑指offerJava中数组字符串的长度获取区别 lengthlength()size()

动态列的 datatable 中 相同行的数据合并,求代码方法

直接将DataTable存入oracle数据库中(转)