Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Некорректная загрузка данных в БД из файла


Автор: Олег13 1.2.2012, 08:14
Всем добрый день!
Посоветуйте как решить проблему.
В общем, у меня есть скрипт который загружает файл CSV на сервер (данный файл представляет из себя прайс-лист радиодеталей). Далее он построчно его читает и загружает строки в БД. Загрузка проходит нормально, все строки загружаются в полном количестве, но не все столбцы заполняются. Например у меня есть две записи в прайсе: 1) "Диоды шоттки; 40CPQ060    TO-247AC; ; 110; Диод Шотки 60v 40A общий катод" и 2) "Диоды шоттки; 40CPQ100; TO-247AC; ; 120; Диод Шотки 100v 40A общий катод". В принципе эти две позиции ничем не отличаются, разве только наименованиями и параметрами. Но в первой записи последняя колонка "Диод Шотки 60v 40A общий катод" загружается в базу нормально, а вот во второй записи последняя колонка "Диод Шотки 100v 40A общий катод" не грузится и остается пустой. Я  просто понять не могу, в чем дело, что не так!? Такое чувство, что загрузка происходит как-то выборочно. В прайсе много таких записей встречается. Для наглядности привожу полный текст скрипта и часть прайс-листа.
Код

#!/usr/bin/perl -w
#use strict;
use DBI;
use CGI;
use CGI qw (:standart);
use CGI qw(:cgi);
use CGI::Carp qw(fatalsToBrowser);

my $ps=param('p1');
my $file = param('price');

$ps=~s/\0//g;
$ps=~s/\.\.//g;

if ($ps ne 'password') {
print "Content-type: text/html\n\n";
print "<html><h1>Неверно введен пароль</h1></html>\n";
exit;
}

if ($file eq '') {
print "Content-type: text/html\n\n";
print "<html><h1>Вы не выбрали файл для загрузки!</h1></html>\n";
exit;
}

##########Загрузка файла на сервер для последующего его чтения и заливки содержимого в БД
my $file_name =$file;
open (FILE, ">/.1/share/elpr.ru/data/temp/$file_name") || die "Can not open file! $file_name!";
binmode FILE;
flock (FILE, 2);
print FILE while (<$file>);
close FILE; 
close $file_name;


########Чтение загруженного файла и заливка его в БД
open FF, "</.1/share/elpr.ru/data/temp/$file_name";
my @n=<FF>;
close FF;


my $dbh=DBI->connect("DBI:mysql:elpr", "elpr", "passw") or die "Error: $DBI::errstr\n";
my $sth=$dbh->do("SET NAMES 'cp1251'");

########## Очистака предыдущего наполнения таблицы
$sql="TRUNCATE TABLE price_new";
$sth=$dbh->do($sql);

foreach $i (@n) {
$u=$u+1;
@m=split(";",$i); 
$m[1]=~s/[\/"']/ /imgx;
$m[2]=~s/[\/"']/ /imgx;
$m[5]=~s/[\/"']/ /imgx;
my $sql="insert into price_new (category,name,body,producer,price_new,description) values (\'$m[0]\',\'$m[1]\',\'$m[2]\',\'$m[3]\',\'$m[4]\',\'$m[5]\')";
$sth=$dbh->do($sql); #Для операций которые не возвращают значение
defined $sth or die $dbh->errstr;
}

$sql="create table temp SELECT price\.category,price\.name,price\.body,price\.producer,price\.price,price\.description,price\.image FROM price LEFT OUTER JOIN price_new ON \(price\.name = price_new\.name\) and \(price\.category = price_new\.category\) and \(price\.\`price\` = price_new\.\`price_new\`\) WHERE \(ISNULL\(price_new\.name\)\) and \(ISNULL\(price_new\.category\)\) and \(ISNULL\(price_new\.\`price_new\`\)\)";
$sth=$dbh->do($sql);

$sql="delete from price where price\.name in \(select temp\.name from temp\)";
$sth=$dbh->do($sql);

$sql="INSERT INTO price \(price\.category, price\.name, price\.body, price\.producer,price\.\`price\`, price\.description, price\.image) SELECT price_new\.category, price_new\.name, price_new\.body, price_new\.producer,price_new\.\`price_new\`, price_new\.description, price_new\.image FROM  price_new LEFT OUTER JOIN price ON \(price_new\.name=price\.name\) and \(price_new\.category=price\.category\) and \(price_new\.\`price_new\`=price\.\`price\`\) WHERE \(ISNULL\(price\.name\)\) and \(ISNULL\(price\.category\)\) and \(ISNULL\(price\.\`price\`\)\)";
$sth=$dbh->do($sql);

$sql="drop table temp";
$sth=$dbh->do($sql);

####Удаление файла из каталога TEMP.Он нам больше не нужен, т.к. мы его уже залили в БД
unlink("/.1/share/elpr.ru/data/temp/$file_name") or die "Can't unlink $file_name: $!";


$dbh->disconnect;

print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print "<title></title>\n";
print "</head>\n";
print "<body>\n";
print "Все готово!!!\n";
print "$u\n";
print "</body>\n";
print "</html>\n";


а вот часть прайс-листа в формате CSV

Диоды шоттки;BAT41;DO-35;;5,5;Диод Шоттки 100В/100мА
Диоды шоттки;BAT42;DO-35;;3,3;Диод Шоттки  30В/200мА
Диоды шоттки;BAT46;DO-35;;5,5;Диод Шоттки 100В/150мА
Диоды шоттки;BAT54A;SOT23;;2,2;Диод Шоттки х2  30В/100мА общий анод
Диоды шоттки;MBR1545CTPBF;TO220AB;;60;Диод Шоттки x2  45В/2х7.5 А Общий катод
Диоды шоттки;MBR3060PT;TO247AD;;90;Диод Шоттки  60В/2х15 А Общий катод
Диоды шоттки;MBR4045PT;TO247AD;;88;Диод Шоттки  45В/2х20 А Общий катод
Диоды шоттки;10BQ060TR PBF;SMB;;8,8;Диод Шотки 60v 1A
Диоды шоттки;10BQ100 100V 1A;SMB;;14;Диод Шотки 100v 1A
Диоды шоттки;10CTQ150 150V 10A;;;55;Диод Шотки 150v 10A общий катод
Диоды шоттки;11DQ10 100V 1.1A;DO-204AL;;9,9;Диоды Шотки 100v 1A
Диоды шоттки;1N5819 40V 1A;;;2,5;Диод Шотки 40v 1A
Диоды шоттки;25CTQ045 2x15A 45V (OK);TO-220;;55;Диод Шотки 2x 45v 30A общий катод
Диоды шоттки;30BQ100 3A 100V SMD;SMD;;17,6;Диод Шотки 100v 3A
Диоды шоттки;30CPQ100 2х30A 100V (OK);TO-247AC (TO-3P);;70;Диод Шотки 100v 30A общий катод
Диоды шоттки;30CPQ150 2x30A 150V (OK);TO-247AC;;78;Диод Шотки 150v 30A общий катод
Диоды шоттки;30CTQ060;TO-220;;44;Диод Шотки 60V 30A 500pF
Диоды шоттки;40CPQ060;TO-247AC;;110;Диод Шотки 60v 40A общий катод
Диоды шоттки;40CPQ080;TO-247AC;;90;OLEG
Диоды шоттки;40CPQ100;TO-247AC;;120;Диод Шотки 100v 40A общий катод
Диоды шоттки;MBR20100CTG;TO-220;;35;Диод Шотки 100v 20A общий катод
Диоды шоттки;MBR20200CT 200V 2x10A TO220;TO-220;;52;Диод Шотки 200v 20A общий катод
Диоды шоттки;MBR4045CTPBF; TO-247;;88;Диод Шотки 45v 40A общий катод
Диоды шоттки;STPS20H100CT 2x10A 100V (OK);TO-220, D2-PAK;;33;Диод Шотки 100v 10A общий катод
Диоды шоттки;STPS5L60;DO-201-AD;;18;Диод Шотки 60V 5A
Диоды шоттки;КД238ВС 45V 7.5A;;;33;

Автор: arto 1.2.2012, 08:40
у вас отличаются форматы строк

Добавлено через 5 минут и 58 секунд
ну и проверяйте коды возврата.

Автор: Олег13 1.2.2012, 17:34
Диоды шоттки;40CPQ060;TO-247AC;;110;Диод Шотки 60v 40A общий катод
Диоды шоттки;40CPQ100;TO-247AC;;120;Диод Шотки 100v 40A общий катод

Где здесь различие формата? Строки идентичны по формату! Даже текст один и тот же, цифры немного отличаются!

и про какие коды вы говорите? 

Автор: arto 1.2.2012, 18:06
1) "Диоды шоттки; 40CPQ060    TO-247AC; ; 110; Диод Шотки 60v 40A общий катод" и 2) "Диоды шоттки; 40CPQ100; TO-247AC; ; 120; Диод Шотки 100v 40A 

между 40CPQ060    TO-247AC пробел.

которые возвращает do.

Автор: Олег13 1.2.2012, 18:37
не, я может туплю конечно, но где пробелы?

Диоды шоттки;40CPQ060;TO-247AC;;110;Диод Шотки 60v 40A общий катод
Диоды шоттки;40CPQ100;TO-247AC;;120;Диод Шотки 100v 40A общий катод


Автор: arto 1.2.2012, 23:04
Например у меня есть две записи в прайсе: 1) "Диоды шоттки; 40CPQ060    TO-247AC; ; 110; Диод Шотки 60v 40A общий катод" и 2) "Диоды шоттки; 40CPQ100; TO-247AC; ; 120; Диод Шотки 100v 40A общий катод". 

Автор: Олег13 2.2.2012, 07:44
Это я о печатался при редактировании записи. Прошу прощения за сей косяк. Реально в файле все нормально, там есть разделитель ";", поэтому проблема точно не в этом.

А насчет кодов, Вы бы не могли поподробнее рассказать? Может примерчик какой дадите? Заранее спасибо.

Автор: Pfailed 2.2.2012, 08:05
Цитата(Олег13 @  1.2.2012,  08:14 Найти цитируемый пост)
1) "Диоды шоттки; 40CPQ060    TO-247AC; ; 110; Диод Шотки 60v 40A общий катод" и 2) "Диоды шоттки; 40CPQ100; TO-247AC; ; 120; Диод Шотки 100v 40A общий катод".

Посчитайте кол-во ";" в 1 и в 2.

Автор: arto 2.2.2012, 08:57
например $dbh->do($sql) or printf "row does not inserted: '%s': %s\n", $sql, $dbh->errstr;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)