有没有办法区分 .NET 中的 SQL Money 和 Decimal 类型?



MoneyDecimalSQL类型在.NET中都被解释为Decimal。有什么办法可以区分吗?我正在尝试正确格式化 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

我找到了这篇文章:.net 中 SQL 的货币数据类型和十进制类型,但不幸的是,我没有标准化的列名,因为这旨在将任何结果集转换为 Excel 电子表格。

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

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

这是我的解决方案...

我在VS2019([TestDb](中创建了一个localdb(v11.0(。德博]。[表](。它有 3 列:

  • 编号(整数(
  • 数字(十进制(18((
  • 美元(货币(

下面是获取架构的代码,然后获取ColumnName及其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;
}

测试对我来说通过了...希望这至少会对您有所帮助。

我以前遇到过类似的问题,我刚刚从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)找到存储过程的元数据。

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

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

并在 .Net 中创建一个由相同属性(名称、重量、成本和库存(组成的类并在那里获取值。

最新更新