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

Truncated DECIMAL values in mysql (30 decimal places)

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

文件中的值以小数点后 30 位的精度存储,例如

125.154821679413246187945612314846

然而,当导入时,数据总是被截断到小数点后 10 位,并带有尾随零,例如

125.154821679200000000000000000000

栏目设置如下:-

USDPayable DECIMAL (33,30)

编辑:

Table 创建脚本:

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 逐行流式传输文件,准备在插入 table 之前处理这些值。使用 fgets(),这个值在这里也被截断了……就好像 mysql 和 php 认为截断的值是文件中正在读取的文字值。很混乱

php 是一种弱类型语言。如果它看到它认为是十进制数的东西,它会默认将其处理为 float -- 一个 ieee 754 双精度近似数。 MySQL.

中的内部数值处理也是如此

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

因此,您为 table 声明高精度小数类型是正确的。但是你必须欺骗 MySQL 来处理你的数字,就好像它们是字符串一样,而不是采用它最喜欢的 ieee 754 快捷方式(或者 hack,我们可能会说)。

您可以尝试这样的操作:

  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 文件中提供某些列。

小心这种货币数据的弱数据类型。请仔细检查您的金额是否正确。您可能需要切换到强类型语言。