【问题标题】:Get maximum length of DataTable column character representation获取 DataTable 列字符表示的最大长度
【发布时间】: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

    ...???
}

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

【问题讨论】:

    标签: c# ms-access


    【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-30
      • 1970-01-01
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      相关资源
      最近更新 更多