【问题标题】:SQL Server rounding issue on insert插入时的 SQL Server 舍入问题
【发布时间】:2011-12-21 16:56:26
【问题描述】:

我有一个计算值为 -1407.858 的应用程序;其 C# 数据类型是 decimal

数据库中的列数据类型为十进制(12,2)。我会认为它会舍入该值并插入 -1407.86(这将满足从零舍入和均匀舍入的情况)。

不幸的是,该值被插入为 -1407.85。我能想到的唯一解释是最后一位数字被截断了。

我在 SQL Server 中做了一些简单的测试查询,例如:

declare @first AS decimal(12,2)
declare @second AS float --[or decimal(12,3)]

set @second = -1407.858
set @first=@second

select @first;

我返回 -1407.86,所以我想 SQL Server 在设置值时会自动舍入值,但在插入时不会。它是否正确? SQL Server是不是只有插入时截断,设置时舍入?

【问题讨论】:

  • 这里有什么问题?
  • 是的,当您将值放入具有两位小数的变量时,它会将值四舍五入到两位小数。
  • @Harry 问题是......? :)
  • @Harry,你是如何插入这个值的?你使用的是 linq2sql、ef 还是任何数据框架?
  • 不要打扰它,在插入之前对结果使用 ROUND 函数。这样您就可以使用您选择的方法显式舍入。

标签: c# sql sql-server


【解决方案1】:

我想 SQL Server 在设置时会自动舍入值 它们,但不是在插入它们时。这是正确的吗?

没有。

DECLARE @T TABLE(C DECIMAL(12,2))
INSERT INTO @T VALUES (-1407.858)
SELECT * FROM @T

返回-1407.86。我认为截断发生在 C# 一侧的某处。

【讨论】:

    【解决方案2】:

    我用Linq2sql做了一个测试,情况如下:

    • 使用 int 主键和 decimal(12,2) 字段映射表;
    • 插入了一个值为 -12.585 的项目;

    执行 SQL Profiler,我发现 linq2sql 已经截断了值,将以下语句发送到服务器:

    exec sp_executesql N'INSERT INTO [dbo].[TestNumbers]([Id], [Number1])
    VALUES (@p0, @p1)',N'@p0 int,@p1 decimal(12,2)',@p0=0,@p1=-12.58
    

    所以你正面临一个 linq2sql 错误。您应该在发送之前对数字进行四舍五入。

    【讨论】:

    • 难道是 Linq2sql 使用了偶数舍入?你用 OP 的值测试过吗?
    • 谢谢,这也是我的想法。
    • @AndriyM 我尝试了许多值,它们都被截断,而不是四舍五入(以任何形式)。
    【解决方案3】:

    decimal(12,2) 总共可以存储 12 位数字,其中两个在逗号后面。所以-1407.858四舍五入为-1407.85是正确的。

    【讨论】:

    • 认为问题是为什么它被截断而不是圆形。但我能想到的最佳答案是“因为它是”,或者可能是“因为这就是文档所说的应该做的”。
    • @Andomar,-1407.858 的正确舍入值(作为小数 (12,2))是 -1407.86。
    • @Dems 如果答案只是“这就是文档所说的应该做的” - 很好;但它是在哪里说的呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多