MySQL: как загрузить данные в формате фиксированной строки в пользовательские переменные - PullRequest
7 голосов
/ 23 ноября 2010

Я пытаюсь загрузить файл, где все строки используют одинаковые правила. (предположим, HEADER - одна строка)

HEADER1
HEADER2
.......

Но, к несчастью, когда я пытаюсь использовать оператор LOAD DATA INFILE, я получаю эту ошибку: Код ошибки: 1409 Невозможно загрузить значение из файла со строками фиксированного размера в переменную .

Это код, который я написал:

USE test;
DROP TABLE IF EXISTS EXAMPLE_H;
CREATE TABLE EXAMPLE_H(
    ID CHAR(20),
    SP CHAR(3),
    IVA CHAR(11) PRIMARY KEY,
    NLP CHAR(6),
    DLP DATE,
    DUVI DATE,
    DELP CHAR(30),
    FILLER CHAR(39),
    VTLP CHAR(3),
    FILL CHAR(49)
);

LOAD DATA INFILE 'BTILSP.TXT' 
    INTO TABLE test.EXAMPLE_H
    FIELDS TERMINATED BY ''
    LINES TERMINATED BY '\n'
    (ID, SP, IVA, NLP, @var_date_one, @var_date_two, DELP, FILLER, VTLP, FILL)
    SET DLP = str_to_date(@var_date_one, '%Y%m%d',
        DUVI = str_to_date(@var_date_two, '%Y%m%d');

У меня была идея прочесть нижнюю часть этой страницы (комментарий Рамама Пуллеллы), и я нашел то же самое объяснение на некоторых сайтах, но я не могу понять, почему я получаю эту ошибку.

Если я не использую переменные @var_date_one и @var_date_two и, таким образом, функцию STR_TO_DATE, дата не отображается в соответствии с требованиями MySql - дата в файле выглядит как «20100701» - тогда это поле будет содержать все нули или дата отличается от того, что я ожидаю. Если я изменю DLP и DUVI для представления в CHAR (8), то это сработает, но я не буду использовать сравнения SQL DATE и подобные инструменты.

Можете ли вы помочь мне, пожалуйста? :) Большое спасибо.

РЕДАКТИРОВАТЬ:

Кажется, проблема дается LINE TERMINATED BY '', так как этот тип линии является "фиксированной строкой (неограниченной)". Может быть, он не может быть назначен переменной по неизвестной причине, но именно так он работает. В документации написано:

Пользовательские переменные нельзя использовать, когда загрузка данных в формате фиксированной строки потому что пользовательские переменные не имеют ширина дисплея.

Есть предложения?

RE-EDIT: Я прочитал комментарий Райана Нева в нижней части этой страницы. Он дает хитрость для чтения фиксированной строки в переменные:

LOAD DATA LOCAL INFILE '<file name>' INTO TABLE <table>
(@var1)
SET Date=str_to_date(SUBSTR(@var1,3,10),'%m/%d/%Y'),
Time=SUBSTR(@var1,14,8),
WindVelocity=SUBSTR(@var1,26,5),
WindDirection=SUBSTR(@var1,33,3),
WindCompass=SUBSTR(@var1,38,3),
WindNorth=SUBSTR(@var1,43,6),
WindEast=SUBSTR(@var1,51,6),
WindSamples=SUBSTR(@var1,61,4);

Как вы думаете, это хороший способ сделать это? :)

Ответы [ 2 ]

3 голосов
/ 06 декабря 2010

Я не эксперт, но мне кажется, что если поля заканчиваются пустой строкой, тогда они должны быть фиксированного размера; должен быть какой-то способ определить границы между полями, и если терминатора нет, тогда они должны быть фиксированного размера.

Я заметил, что в руководстве MySQL 5.5 написано:

  • Пользовательские переменные нельзя использовать при загрузке данных в формате фиксированной строки, поскольку пользовательские переменные не имеют ширины отображения.

Это также (довольно ранее на странице) говорит:

  • Если значения FIELDS TERMINATED BY и FIELDS ENCLOSED BY являются пустыми (''), используется формат с фиксированной строкой (неограниченный). В формате с фиксированной строкой разделители между полями не используются (но вы все равно можете использовать ограничитель строки). Вместо этого значения столбцов читаются и записываются с использованием ширины поля, достаточно широкой, чтобы в ней могли храниться все значения. Для TINYINT, SMALLINT, MEDIUMINT, INT и BIGINT значения ширины поля равны 4, 6, 8, 11 и 20 соответственно, независимо от заявленной ширины экрана.

Поскольку в вашем утверждении нет полей, включенных в поле, и пустых полей, поэтому у вас фиксированный формат. И поэтому вы не можете делать, как хотите.


В некоторых случаях легче обрабатывать данные за пределами СУБД - исправление представления данных может быть одной из таких операций. У меня есть программа, которую я называю DBLDFMT, которую я не использовал уже несколько лет, но она может выполнять различные операции, такие как преобразование десятичных чисел с неявными десятичными точками (трюк мэйнфрейма; поле цены может быть 0023199 представляя значение £ 231,99). Он также может иметь дело с манипуляциями с датами (необязательно с использованием особенно удобной для пользователя записи, но он способен решать проблемы, с которыми я столкнулся при получении данных с мэйнфреймов в СУБД Unix - не MySQL; его не было, когда я писал это код. Свяжитесь со мной, если это может быть интересно - см. мой профиль.

1 голос
/ 05 января 2016

В случае, если кто-то еще сталкивается с этим.Если вы просто запустите

LOAD DATA LOCAL INFILE '<file name>' INTO TABLE <table> (@var1) SET ...

без указания FIELDS TERMINATED BY, и ваш файл содержит запятые, MySQL по умолчанию разделится на них.

В таком случае вы можете простоскажите MySQL, что ваш разделитель полей - это что-то глупое.Например:

FIELDS TERMINATED BY '@@@@@@@@@@@@'

Таким образом, вся строка помещается в первый «столбец», то есть в вашу пользовательскую переменную.Затем вы можете использовать его в точности так, как показано в коде вверху.

Стоит отметить, что MySQL обрабатывает разделитель строки, поэтому вы даже можете иметь
FIELDS TERMINATED BY 'this_string_thoes_not_appear_in_my_file, если хотите

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...