mysql中截断的DECIMAL值(小数点后30位)

时间:2017-05-18 10:26:20

标签: php mysql financial

我目前正在使用LOAD DATA LOCAL INFILE来导入批量财务数据以进行处理。

文件中的值存储精确到30个小数位,例如

125.154821679413246187945612314846

但是,当导入时,数据总是被截断为10个小数位,并带有尾随零,例如

125.154821679200000000000000000000

列设置如下: -

USDPayable DECIMAL (33,30)

编辑:

表创建脚本:

CREATE TABLE IF NOT EXISTS dump
                        (
                            SaleID INT NOT NULL AUTO_INCREMENT,
                            Country VARCHAR(8),
                            Label VARCHAR(20),
                            Product VARCHAR(5),
                            URI VARCHAR(20),
                            UPC VARCHAR(20),
                            EAN VARCHAR(20),
                            ISRC VARCHAR(20),
                            TrackName VARCHAR(28),
                            ArtistName VARCHAR(64),
                            ComposerName VARCHAR(64),
                            AlbumName VARCHAR(54),
                            Quantity INT(10),
                            USDPayable decimal(33,30),
                            PRIMARY KEY (SaleID)
                        );

加载数据脚本:

LOAD DATA 
  LOCAL INFILE '<my file>'
    INTO TABLE dump
        IGNORE 3 LINES
              (Country, Label, Product, URI, UPC, EAN, ISRC, 
               TrackName, ArtistName, ComposerName, AlbumName,
               Quantity, USDPayable)

输入数据样本:

BE Label1 product code 00cflHmwefweidJA barcode ISRC ......... 1 0.003872402660862401479116078884
US Label2 product code 00cflHmtyfweidJA barcode ISRC ..........1 0.002220695558213356018688393633
BE Label2 product code 00cflHmwefweidJA barcode ISRC ..........2 0.002137613958913373918420510406
NO Label3 product code 00cflHmjkfweidJA barcode ISRC ..........3 0.02264616748080050066133527663
DE Label4 product code 00cflHmwefweidJA barcode ISRC ..........1 0.003018216435957714580945696704
CO Label5 product code 00cflHmzxfweidJA barcode ISRC ..........1 0.0004178407583000146349569881848
CA Label6 product code 00cflHmwefpoidJA barcode ISRC ..........2 0.01385864190292964399955986534
CA Label7 product code 00cflHmwefmnidJA barcode ISRC ..........1 0.003270121556795672746439239972
IS Label7 product code 00cflHmwefweidJA barcode ISRC ..........8 0.05702767311942350853930831032
TR Label7 product code 00cf09poefweidJA barcode ISRC ..........4 0.009839895102632677068730014884

更新

过了一会儿,我决定咬紧牙关 - 然后使用PHP逐行流式传输文件,以便在插入表之前处理这些值。使用fgets(),这个值也被截断了......这几乎就像mysql和php认为截断的值是文件中的文字值,因为它正被读取。非常混乱

1 个答案:

答案 0 :(得分:1)

php是一种弱类型语言。如果它看到它假设的是十进制数,它将其处理为float - 一个ieee 754双精度近似数 - 默认情况下。 MySQL中的内部数字处理也是如此。

ieee 754双精度对于你的版税计算来说还不够精确(可怜的音乐家;你不能用百万分之一便士购买任何东西)。

因此,您可以为您的表声明一个高精度的十进制类型。但你必须欺骗MySQL处理你的数字,好像它们是字符串一样,而不是采用它最喜欢的ieee 754快捷方式(或黑客,我们可能会说)。

您可以尝试这样的事情:

  LOAD DATA 
LOCAL INFILE 'C:\\yadda\\yadda\\sample.tsv'
  INTO TABLE dump
             (Country, Label, Product, URI, UPC, ISRC, Quantity, @USDPayable)
         SET USDPayable = CAST(@USDPayable AS DECIMAL(33,30) );

这将安排在输入中处理您的小部分美元作为字符串,然后使用SET子句将其转换为您需要的十进制格式。

请注意括号中的列列表如何将每列中的值分配给@USDPayable

这对我有用。如果它不适合您,您可能应该考虑转移到更高版本的MySQL。

请注意,您必须更改实际数据的列列表。您没有在示例tsv文件中提供一些列。

小心使用这种货币数据进行弱数据输入。请仔细检查您的款项是否正确。您可能需要切换到强类型语言。