如何获得数字列的确切类型,包括。规模和精度?

Posted

技术标签:

【中文标题】如何获得数字列的确切类型,包括。规模和精度?【英文标题】:How to get the exact type of numeric columns incl. scale and precision? 【发布时间】:2014-08-01 14:24:07 【问题描述】:

有没有办法知道DataTable 中列的确切类型?现在我正在这样做:

DataTable st = dataReader.GetSchemaTable();
foreach (DataColumn col in st.Columns)

   var type = col.DataType;

现在有了type.Name,我可以找到它是数字(intdecimal..)还是string,但问题是我需要确切的类型,例如如果在数据库中让说列RateNUMBER(4,3),那么在我的代码中,我只得到类型为“十进制”并且没有关于格式4,3 的信息。

现在的要求是我需要根据它们的类型来格式化这些值,例如。如果Rate=1.4 应该显示为0001.400(根据格式NUMBER(4,3))。因此,由于我没有信息,因此在这里我无法进一步处理这些值。反正有知道的吗?

谢谢

【问题讨论】:

msdn.microsoft.com/en-IN/library/… 循环遍历每一行又名 DataRow 并使用个体的反射 getType.. 您需要查看列上的其他属性才能准确确定。例如查看 NumericPrecision 和 NumericScale 属性 msdn.microsoft.com/en-us/library/… @Tim Schmelter :请通过一些关于如何使用它的说明。我可以在 DataTable 或 DataColumn 中找到它。 【参考方案1】:

您可以使用NumericPrecisionNumericScale

using (var con = new SqlConnection(Properties.Settings.Default.MyConnectionString))
using (var cmd = new SqlCommand("SELECT * FROM dbo.Test", con))

    con.Open();
    using (var reader = cmd.ExecuteReader())
    using (var schemaTable = reader.GetSchemaTable())
    
        foreach (DataRow row in schemaTable.Rows)
        
            string column = row.Field<string>("ColumnName");
            string type = row.Field<string>("DataTypeName");
            short precision = row.Field<short>("NumericPrecision");
            short scale = row.Field<short>("NumericScale");
            Console.WriteLine("Column: 0 Type: 1 Precision: 2 Scale: 3", column, type, precision, scale);
        
    

更多信息:GetSchemaTable

我已经用一个新表进行了测试,该表具有NumberColumn 类型的numeric(4, 3) 类型的单列:

Column: NumberColumn Type: decimal Precision: 4 Scale: 3

【讨论】:

这正是我正在寻找的。我已经在我的代码中尝试过这个并获得了所需的值。非常感谢! +1 只是一个附加问题。有什么方法可以从 Schema 表中获取特定的列数据行。例如,仅对于 Rate 列,我如何获取数据行。我这样做了: 1. schemaTbale.rows 上的 Foreach 循环 2. schemaColName = row.Field("ColumnName"); 3. 如果 schemaColName="Rate" 获取所有其他数据。但是,对于每一列,我都在遍历完整的 schemaTable .. 有没有更好的方法来做到这一点?提前致谢。 @LittleMissSunshine:为什么这是个问题?无论如何,您不应该有几十列。您可以使用 LINQ(这也是一个隐藏循环):var row = tbl.AsEnumerable().First(r =&gt; r.Field&lt;string&gt;("ColumnName")=="Rate"); 你是对的,在任何情况下,Schema 表都会为每一列至少遍历一次。在这种情况下,LINQ 和 Loop 将做同样的事情。既然没有。的列是有限的,它不会像我最初想象的那样影响性能。再次感谢! @LittleMissSunshine:性能根本不应该成为问题,因为整个DataTable 已经在内存中而且它非常小。但是,对于它的价值,您可以从 DataTable 创建一个 Dictionary 以更快地按其名称查找列。所以键是列名,值是DataRow。您可以使用 LINQ:var dict=tbl.AsEnumerable().ToDictionary(r =&gt; r.Field&lt;string&gt;("ColumnName"), r =&gt; r);【参考方案2】:

dataReader.GetSchemaTable() 返回的 DataTable 是底层结果的架构。该表包含的记录数与基础表中的列数一样多。所以你需要遍历行。每行包含基础表的单个列的元数据。您可以获取该列的元数据,如下所示

DataTable st = reader.GetSchemaTable();
                    foreach (DataRow row in st.Rows)
                    
                        Console.Write(string.Format("ColumnName:0 DataType:1 Ordinal:2 Precision:3 Size:4 Scale:5", 
                            row["ColumnName"], row["DataTypeName"], row["ColumnOrdinal"], 
                            row["NumericPrecision"], row["ColumnSize"], row["NumericScale"]));
                    

【讨论】:

以上是关于如何获得数字列的确切类型,包括。规模和精度?的主要内容,如果未能解决你的问题,请参考以下文章

如何解释数据库中数字的精度和比例?

没有精度的Oracle数字类型 - 我怎么知道它是否是整数

如何将两个整数相除以获得双精度?

如何在蜂巢中获得毫秒精度?

js精度计算

如何处理由于分组函数而导致的 JDBC 数字类型的精度损失