【问题标题】:Wrong output when reading decimal value from database从数据库读取十进制值时输出错误
【发布时间】:2011-03-26 17:57:35
【问题描述】:

我有一个奇怪的问题,我就是想不通。我将货币作为小数存储在我的数据库中。我正在读取 CSV 文件并将字符串转换为十进制以存储在数据库中。检查数据库时,这些值似乎没有正确存储,大多数都正确存储,但由于某种原因,我拥有的值 1000 存储为 1,而 2299 存储为 2,因此显然存在数字超过 999.99

我运行了一个数据库迁移如下:

def self.up
change_column(:transactions, :in, :decimal, :precision => 8, :scale => 2 )
change_column(:transactions, :out, :decimal, :precision => 8, :scale => 2)
end

这是用于存储 CSV 文件中的值的代码:

def create

data = params[:dump][:file].read

FasterCSV.parse(data, :headers => true) do |row|

  transaction = Transaction.new
  transaction.date = Date.strptime(row[0], "%d/%m/%Y")
  transaction.transaction_type = row[4]
  transaction.details = row[3]

  if row[7].to_f < 0
    transaction.out = row[7].to_d.abs
  else
    transaction.in = row[7].to_d.abs
  end
  transaction.save

(.abs 是因为付款值只是作为负值存储在 CSV 文件中)。

当我使用控制台创建一个新事务并转换一个 1000 的字符串并使用相同的方法存储它时,它工作正常并且值存储为 1000.0。

有人知道为什么会这样吗?虽然这是一个 FasterCSV 问题,但我认为如果 CSV 数字没有被正确读取是可能的。

感谢您的帮助,

汤姆

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 bigdecimal fastercsv


    【解决方案1】:

    您是否查看过值 >= 1000 的行的原始 CSV 数据?在我看来,数据是每 3 位数用逗号格式化的,在这种情况下,to_d 方法将忽略第一个逗号之后的所有内容。

    >> '1,123.41'.to_d
    => #<BigDecimal:10593e0a8,'0.1E1',9(18)>
    

    如果这是问题所在,只需使用 gsub 去掉逗号即可。

    >> '1,123.41'.gsub(',','').to_d
    => #<BigDecimal:105932398,'0.112341E4',18(18)>
    

    【讨论】:

    • 非常感谢您的建议。我没有意识到,因为当我在开放式办公室打开 CSV 时,它删除了所有格式,所以我只看到它为 1000,甚至没有考虑其中可能有逗号。
    猜你喜欢
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多