【问题标题】:Why update trigger is making rounding in SQL Server?为什么更新触发器在 SQL Server 中进行舍入?
【发布时间】:2018-07-07 21:38:10
【问题描述】:

我在名为“项目”的表中的一个项目的价格是 1.5750,只要价格发生变化,它就会更新到另一个表

这是我的更新触发器

update Ss
    set price = cast( i.Price * 100 as int)
    from    Updateitems ss
    
    inner join inserted i on i.ItemNo = ss.ItemNo

在项目表中,价格为 1.5750

更新后,UpdateItemTable 上的价格显示为158

但是当我像这样直接执行查询时select cast( 1.5750 * 100 as int) 输出显示 157

为什么要更新158?

哪个是正确的?

注意:

价格数据类型是item 表上的钱

Updateitems 表中的价格数据类型为 varchar

【问题讨论】:

  • 列 i.Price 数据类型?
  • @jarlh 你能检查我的更新吗?
  • 试试select cast(cast(1.5750 as money) * 100 as int) ...
  • 顺便说一句,为什么价格列的数据类型不同?
  • @jarlh 请等一下兄弟。我会检查

标签: sql sql-server casting triggers sql-update


【解决方案1】:

您将十进制值 1.5750 乘以 100,这是正确的,得到 157.50,但随后您将其转换为 int 数据类型,整数数据类型,只能保存整数值,所以当它们被赋予一个十进制值时,它们会四舍五入到(通常)最接近的整数,这就是为什么你会看到它返回为 158。

如果您想保留十进制值,您可以将其转换为小数;

select cast( 1.5750 * 100 as decimal(5,2))

decimal(5,2) 允许您在小数点后有 2 个数字(通常用于货币值),并且仍然保留您之前的 3 个数字。

【讨论】:

    【解决方案2】:

    “如果 SQL Server 对 MONEY 数据类型执行计算,则中间值在内部存储为 MONEY 数据类型。由于 MONEY 仅表示小数点右侧的四个位,因此任何需要 5 个或更多位的计算小数表示会产生舍入误差。"

    Source

    如果无法更改数据类型,请将更新更改为以下。

    update Ss
        set price = cast( cast(@Price as float) * 100 as int)
        from    Updateitems ss
    
        inner join inserted i on i.ItemNo = ss.ItemNo
    

    【讨论】:

    • 我不想浮起来
    • 如果您想要一个精确的十进制数据类型,则不应使用浮点数,大多数人在处理货币时倾向于使用浮点数。您应该使用 decimal 并选择适当的精度和比例。
    • @Liamneesan 理想情况下,您应该更改数据类型
    【解决方案3】:

    您将值转换为 INT,最终得到 157

    SELECT cast( cast(@Price as float) * 100 as decimal(5,2))
    

    【讨论】:

      猜你喜欢
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 1970-01-01
      相关资源
      最近更新 更多