我们最近收到的投诉是,最终数量开始显示为4位小数,如1.2300
而不是1.23
,使用Sql Server DB。我们的应用程序并不完美 - 到了最后它只需要调用
Convert.ToString(reader("field"))
但在我们直接使用OleDb
提供商之前,几年前我们开始使用抽象提供商,幕后使用基于连接设置的SqlClient
或ODP.NET
。
以下是调用Convert.ToString(reader("field"))
OLEDB
数据库字段为十进制 - 读者数据类型为
decimal
,返回为1.0000
数据库字段为资金 - 读者数据类型为decimal
,返回为1.00
< -
的SqlClient
数据库字段为十进制 - 读者数据类型为
decimal
,返回为1.0000
数据库字段为资金 - 读者数据类型为decimal
,返回为1.0000
< -
应用程序是> 10yo,据我所知,整个事情投入了事实 Money 返回0.00
和字段 Decimal 返回任何精度。
但我想知道这是否是某种无意的行为?除非我找到天才解决方案,否则在相当大的代码库中全局修复它可能需要付出一些显着的努力。
答案 0 :(得分:0)
依赖于类型的默认格式是最好的短视,应该避免使用指定特定格式。
ToString
System.Decimal
方法使用其比例因子来确定小数点右侧显示的位数。可以使用重载来设置构造函数中的比例因子:Decimal Constructor (Int32, Int32, Int32, Boolean, Byte)
。
SQL Server money
类型由.Net读取为System.Decimal
。 SQLClient提供程序将类型的内部比例设置为4.在我的测试中,SQL Server Native Client中的OLE DB提供程序根据检索的值设置比例,比例范围可以从0到4。
出于本答案的目的,假设一个具有此模式的表。
CREATE TABLE [dbo].[TestSQLD_M](
[ID] [int] NOT NULL,
[D2] [decimal](18, 2) NULL,
[D4] [decimal](18, 4) NULL,
[M] [money] NULL,
CONSTRAINT [PK_TestSQLD_M] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
D2.ToString
会产生:#。##
D4.ToString
会产生:#。####
M.ToString
会产生:#或#。#或#。###或#。####取决于M
要强制M
使用默认格式#.##
,您可以使用SQL decimal
子句中的所需比例因子将值转换为Select
。所以而不是:
Select ID, D2, D4, M From TestSQLD_M
使用:
Select ID, D2, D4, Cast(M As decimal(18,2)) As M From TestSQLD_M
这将使用SQLClient
或OLE DB Provider in SQL Server Native Client
生成相同的格式。