В настоящее время я использую 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 думали, что усеченные значения являются литеральными значениями в файле во время его чтения. Очень запутанно
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 файла.
Будьте осторожны со слабой типизацией данных с такими денежными данными. Пожалуйста, проверьте, чтобы ваши суммы были правильными. Возможно, вам придется переключиться на строго типизированный язык.
Других решений пока нет …