2014-04-01 70 views
0

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

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 

    ...??? 
} 

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

回答

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

访问在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; 
      } 
     } 

    } 
} 
+0

的信息像'sys.columns'可能在这种情况下提供的唯一有用的部分是列名,这在我的情况下,直接从'oleReader.GetSchemaTable来()'。 –

+0

是的,在这种情况下是真的。如果你打算在服务器上完成所有这些工作,你可以使用sys.columns来创建动态查询,而不是使用datareader。 – Brad