загрузить данные в MySQL и избежать дублирования записей - PullRequest
0 голосов
/ 23 января 2012

Я выполняю следующий код в моем Perl-файле:

LOAD DATA INFILE 'file_name'
INTO TABLE tbl_name
FIELDS TERMINATED BY ','
(columns..., @var, morecolumns...)
SET datecolumn = str_to_date(@var, '%d/%m/%Y');

У меня есть 2 вопроса:

  1. когда я запускаю файл perl, я получаю следующую ошибку. Означает ли это, что мне нужно добавить поле 'var' в мою таблицу в БД?

    Глобальному символу "@var" требуется явное имя пакета в строке process.pl 37. Выполнение process.pl прервано из-за ошибок компиляции.

  2. Если по какой-либо причине мне придется перезагрузить данные из файлов .csv и запустить эту команду еще раз, она добавляет новые записи как дубликаты. Как я могу отредактировать приведенный выше код, чтобы избежать дублирования записей?

ОБНОВЛЕНО соответствующий код из Perl:

 my $sql = "LOAD DATA LOCAL INFILE '$fname' INTO TABLE $tname FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' (trade_dt,t_id,....open_int);";
 print $sql,"\n"; #date is going in as '0000-00-00'
  $dbh->do($sql) or die $dbh->errstr;

это то, что он показывает в MySQL

mysql> select max(trade_dt) from test;
+---------------+
| max(trade_dt) |
+---------------+
| 0000-00-00    |
+---------------+
1 row in set (0.04 sec)

Насколько я понимаю, мне нужно было добавить SET trade_dt=str_to_date(), чтобы получить дату в моей БД как yyyy-mm-dd. В файле .csv, который я загружаю в БД, дата указывается в формате dd/mm/yyyy

Также, если это поможет, вот как trade_dt объявляется в таблице mySQL, тест:

trade_dt date NOT NULL

Ответы [ 4 ]

1 голос
/ 23 января 2012

Сообщение об ошибке в первом вопросе означает, что Perl интерпретирует @var в этой строке как имена глобальных массивов Perl @var, а не как переменную SQL. Это также означает, что вы сказали use strict в начале вашей программы, и это здорово!

Исправлено - экранирование специального символа @ в строке:

(columns..., \@var, morecolumns...)
SET datecolumn = str_to_date(\@var, '%d/%m/%Y');
0 голосов
/ 23 января 2012

Ошибка Global symbol @var.. исходит из perl и означает, что ваша переменная @var не объявлена ​​в текущей области. Предполагая, что он используется правильно, вы можете объявить его с помощью my @var. Если это не переменная perl, вам нужно заключить строку в одинарные кавычки, чтобы избежать интерполяции переменных. Трудно сказать, что вы должны делать, поскольку вы ничего не показываете в своем коде. Например:

my $query = q#LOAD DATA INFILE 'file_name'
INTO TABLE tbl_name
FIELDS TERMINATED BY ','
(columns..., @var, morecolumns...)
SET datecolumn = str_to_date(@var, '%d/%m/%Y');#;

Обратите внимание, что q() будет принимать альтернативные разделители, в зависимости от ваших потребностей, например #, и будет препятствовать интерполяции переменных в строке.

Если это переменная perl, вам, вероятно, следует использовать заполнители и модуль DBI (или аналогичный) для дополнительной безопасности. Массив @var, если он находится внутри строки в двойных кавычках, будет расширен и дополнен пробелами (если для $" установлено значение по умолчанию), что может быть не совсем тем, что вы хотите. E.g.:

my @var = ("foo", "bar", "baz");
print "@var";

Напечатает foo bar baz.

0 голосов
/ 23 января 2012

Можно ли использовать «ЗАМЕНА» вместо «ВСТАВКА»?Если нет, то можете ли вы очистить стол перед выполнением вставки?

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

0 голосов
/ 23 января 2012

Для второго вопроса загрузите данные во временную таблицу, а затем с помощью курсора прочитайте строки во временной таблице и вставьте их в реальную таблицу, избегая дублирования с некоторым логическим кодом (где условие, если существует управление структурой и т. Д.).

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