2017-05-18 43 views
1

我目前使用LOAD DATA LOCAL INFILE导入批量财务数据进行处理。mysql中截断的DECIMAL值(小数点后30位)

将文件内的值存储到精确度为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 

UPDATE

一段时间后,我决定硬着头皮 - 和流文件中的行由行使用PHP准备好在插入表之前处理值。使用fgets(),这个值在这里也被截断......这就好像mysql和php认为被截断的值是文件中正在读取的文字值。非常容易混淆

+0

尝试number_format() –

+0

@BilalAhmed你可以扩展一下吗?如果你的意思是php函数,我希望避免任何预处理(这解释了使用LOAD DATA LOCAL INFILE),因为该文件包含数十万行 – locksem

+0

请考虑编辑你的问题以显示我们有几行输入文件,以及SHOW CREATE TABLE的输出,无论您尝试加载哪张表。它看起来像MySQL正在从你的'INFILE'读取数字,将它们转换为其内部本地数字格式 - 双精度浮点数 - 然后将它们转换为十进制数,从而失去精度。您可以尝试用引号将这些数字包装起来,这样'LOAD DATA INFILE'就会假定它们是文本字符串,而不是数字。 –

回答

1

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

ieee 754 double precision对于您的版税计算来说不够精确(可怜贫穷的音乐家;你无法用百万分之一的钱购买任何东西)。

所以你是正确的为你的表声明一个高精度的十进制类型。但是你必须欺骗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)); 

这将安排处理您的美元微小的分数上输入一个字符串,然后将其转换到你需要使用一套条款十进制格式。

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

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

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

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

+1

我很容易向向音乐家支付版税的人寻求帮助。我的家人和朋友中有很多音乐家。 –

+0

非常感谢@ O.Jones,这似乎很好地完成了这个诀窍 - 还有很多额外的有用信息。这让我相当怀疑继续依赖于PHP这种事情! – locksem