代码之家  ›  专栏  ›  技术社区  ›  Dryden Long

是否有一种方法可以区分SQL Money和Decimal类型。网

  •  2
  • Dryden Long  · 技术社区  · 8 年前

    Money 和 Decimal SQL类型都被解释为 十进制的 在里面网有什么办法能区分这两者的区别吗?我正在尝试正确设置Excel电子表格的格式,但不知道哪些字段应设置为货币格式,哪些字段应设置为小数。例如:

    +----------------+------------------+--------------+-----------------+
    | Name (VarChar) | Weight (Decimal) | Cost (Money) | Inventory (Int) |
    +----------------+------------------+--------------+-----------------+
    | Widget         | 3.75             | 9.99         |              25 |
    +----------------+------------------+--------------+-----------------+
    

    上面的标题包括用于此问题的数据类型,以及 query 作为从该表中选择的存储过程:

    var result = conn.Query<dynamic>(query, parameters, commandType: CommandType.StoredProcedure).ToList();
    
    foreach (var pair in (IDictionary<string, object>)result[0]) {
      Console.WriteLine($"{pair.Key}: {pair.Value.GetType().Name}");
    }
    

    将导致:

    Name: String
    Weight: Decimal
    Cost: Decimal
    Inventory: Int32
    

    我发现了这个帖子: Money datatype and decimal type of SQL in .net 但不幸的是,我没有标准化的列名,因为这是为了将任何结果集转换为Excel电子表格。

    我还考虑过在需要时将存储过程更改为预先挂起美元符号,但这将需要更多的工作,而且很可能会破坏其他功能。

    有没有其他方法来确定结果的SQL类型?

    3 回复  |  直到 8 年前
        1
  •  2
  •   Kaz    7 年前

    这是我的解决方案。。。

    我在VS2019中创建了一个localdb(v11.0)( [TestDb]。[dbo]。[附表] ).它有三列:

    • Id(整数)
    • 数字(十进制(18))
    • 美元(货币)

    下面是我的代码,用于获取模式,然后获取 字段名 以及它的 ProviderSpecificDataType :

        [TestMethod]
        public void GetProviderSpecificDataType()
        {
            using (SqlConnection connection = new SqlConnection("Server=(localdb)\\v11.0;Integrated Security=true;"))
            {
                connection.Open();
                SqlCommand cmd = connection.CreateCommand();
                cmd.CommandText = "select * from [TestDb].[dbo].[Table]";
                SqlDataReader reader = cmd.ExecuteReader();
                DataTable table = reader.GetSchemaTable();
    
                var columnTypes = GetColumnTypes(table);
    
                Assert.AreEqual("SqlInt32", columnTypes["Id"]);
                Assert.AreEqual("SqlDecimal", columnTypes["Number"]);
                Assert.AreEqual("SqlMoney", columnTypes["Dollars"]);
            }
        }
    
        private Dictionary<string, string> GetColumnTypes(DataTable table)
        {
            Dictionary<string, string> data = new Dictionary<string, string>();
    
            foreach (DataRow row in table.Rows)
            {
                string columnName = row["ColumnName"].ToString();
                string dataType = ((Type)row["ProviderSpecificDataType"]).Name;
    
                data[columnName] = dataType;
            }
    
            return data;
        }
    

    我考试及格了。。。希望这至少能帮到你。

        2
  •  1
  •   zambonee    8 年前

    我以前也遇到过类似的问题,我刚刚从 sys.columns INNER JOIN sys.types ON columns.user_type_id = types.user_type_id .但看起来您正在使用存储过程。在SQL Server 2012及更高版本中,可以使用 sys.dm_exec_describe_first_result_set_for_object(@object_id,1) .

        3
  •  0
  •   Calyfs0    7 年前

    我建议您使用SQL中可编程性(用户定义类型)下的类型。

    您可以创建一个类型,就像我们在SQL中创建一个由名称、重量、成本和库存组成的类一样,在返回这些值的过程中,将它们添加到刚才创建的用户定义类型中,并将其作为集合发送。

    然后进去。Net创建一个由相同属性(名称、重量、成本和库存)组成的类,并从中获取价值。