2017-05-18 79 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