|
|
|
| Подскажите, как реализовать загрузку exсel файла в БД? Функция LOAD DATA запрещена на хосте. Выдает вот такое сообщение The used command is not allowed with this MySQL version, вычетал в инете. Проблема в том что файлы большие, прайсы где-то по 10000-30000 найменований. Как мне кажется, не очень удачно будет проходить INSERT-ом каждое значение. Надо типа админки, чтоб каждый мог загружать свой прайс. В PhpMyAdmin пускать всех нельзя естественно. Как быть? Заранее спасибо. | |
|
|
|
|
|
|
|
для: magic
(14.03.2010 в 15:25)
| | . | |
|
|
|
|
|
|
|
для: magic
(14.03.2010 в 15:25)
| | Вам сообщили - в этой версии MySQL эту команду не применить.
Вы же даже эту самую версию не привели.
Что Вы ждете?
И таки существуют многострочные INSERTs. Совсем неолбязательно на каждую строку клепать отдельный запрос. | |
|
|
|
|
|
|
|
для: Trianon
(15.03.2010 в 13:23)
| | На хосте phpinfo() показывает версия 5.0.81, у меня локально 5.0.27, но у меня все нормально. Ну я так понял что это сообщение выскакивает когда запрещают использование load data. По крайнер мере так было написано на сайте http://php.su/mysql/manual/?page=LOAD_DATA_LOCAL. Только я там не понял насчет версий. | |
|
|
|
|
|
|
|
для: magic
(15.03.2010 в 20:16)
| | Что ж, прошу прощения, возможно на счет блокировки Вы и правы.
Тогда придется таки применять многострочный INSERT . | |
|
|
|
|
|
|
|
для: Trianon
(15.03.2010 в 23:58)
| | Я понял, ну что тогда придется многострочный INSERT применять. Теперь возникает другой вопрос. В БД есть шесть столбцов, в файле тоже есть шесть столбцов с данными. Как организовать заполнение INSERTa из файла что бы получилось так INSERT INTO tb1 VALUES (1, 'процессоры'), (2, 'видеокарты'), (3, 'мат.платы'), или что то подобное. Я думаю, циклом заполнять массив, считывать строку с разделителями до конца строки. Хотел бы узнать в правильном направлении я двигаюсь. Спасибо | |
|
|
| |
|
|
|
|
для: Trianon
(16.03.2010 в 11:33)
| | Там не много непонятно. И все как разобрать массив что бы получилось INSERT INTO tb1 VALUES (1, 'процессоры'), (2, 'видеокарты'), (3, 'мат.платы'). Получается $data[$i] вносит только одно значение.
<?php
$csv_file="book1.csv";
$fp=fopen($csv_file, "r");
while($data=fgetcsv($fp, 1000, ";"))
{
$cnt=count($data);
for($i=0; $i<$cnt; $i++)
{
echo $data[$i];
}
}
fclose($fp);
?>
|
| |
|
|
|
|
|
|
|
для: magic
(17.03.2010 в 15:25)
| | Вы полагаете, на Ваш вопрос можно ответить что-то путное, не зная структуры данных ни CSV-таблицы ни SQL-таблицы? | |
|
|
|
|
|
|
|
для: Trianon
(17.03.2010 в 15:57)
| | Хорошо не вопрос Вы только скажите и все будет, вот такие данные. В цикле for вывод информации (echo) для наглядности.
CREATE TABLE `price` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`name1` varchar(255) default NULL,
`name2` varchar(255) default NULL,
`name3` varchar(255) default NULL,
`name4` varchar(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
|
<?php
$csv_file="book1.csv";
$fp=fopen($csv_file, "r");
while($data=fgetcsv($fp, 1000, ";"))
{
$cnt=count($data);
for($i=0; $i<$cnt; $i++)
{
echo $data[$i];
}
}
fclose($fp);
?>
|
979002;Провод жгут;3;14,89 Грн.;27,24 Грн.
979003;Провод жгут;4;;25,31 Грн.
979006;Провод жгут;8;14,89 Грн.;27,24 Грн.
979008;Провод жгут;10;14,89 Грн.;27,24 Грн.
979009;Провод жгут;1;;27,24 Грн.
979010;Провод жгут;9;14,89 Грн.;27,24 Грн.
979011;Провод жгут;9;20,18 Грн.;37,06 Грн.
979012;Провод жгут;4;20,18 Грн.;37,06 Грн.
979013;Провод жгут;10;14,89 Грн.;27,24 Грн.
979016;Провод жгут;11;;37,06 Грн.
|
| |
|
|
|
|
|
|
|
для: magic
(17.03.2010 в 16:20)
| | name1 name2 name3 быть не должно.
Зато должно быть что-то вроде qty, price_opt, price_rozn
<?php
$csv_file="book1.csv";
$fp=fopen($csv_file, "r");
$newline = "INSERT INTO 'price_table(id, name, йенб price_opt, price_rozn) VALUES'"
$SQL = '';
while($data=fgetcsv($fp, 1000, ";"))
{
list($id, $name, $qty, $price_opt, $price_rozn) = $data;
$id = (int) $id;
$qty = (float) $qty;
$price_opt = (float)str_replace(',','.', $price_opt );
$price_rozn = (float)str_replace(',','.', $price_rozn );
$name = "'".mysql_real_escape_string($name)."'";
$sql .= "$newline \r\n ($id, $name, $qty, $price_opt, $price_rozn)";
$newline = ',';
}
fclose($fp);
// $sql = "\r\n ON DUPLICATE KEY UPDATE\r\n SET ..."; // действия при повторе ключей
?>
|
Теперь в $sql будет что-то адекватное требуемому. | |
|
|
|
|
|
|
|
для: Trianon
(17.03.2010 в 16:45)
| | Спасибо за помощь. Все работает. А для чего здесь приводится перевод строки в
$sql .= "$newline \r\n ($id, $name, $qty, $price_opt, $price_rozn)";
|
| |
|
|
|
|
|
|
|
для: magic
(19.03.2010 в 12:22)
| | Судя по оформлению Ваших реплик в этой теме (а они все идут одной строкой), я не смогу Вам этого объяснить. | |
|
|
|
|
|
|
|
для: Trianon
(19.03.2010 в 12:24)
| | Ну как бы, что тут непонятного. Вы мне помогли со скриптом выше, все работает, спасибо. Там есть переменная $sql, я спросил для чего в ней применяется конец строки. Вот и все. | |
|
|
|
|
|
|
|
для: magic
(14.03.2010 в 15:25)
| | Кто подскажет, имеется проблема. Скрипт (тот который выше в этой теме) для загрузки БД работает, но почему то только если количество строк меньше 589. Если строк больше то выдает вот такую ошибку Illegal double '01E311115' value found during parsing. На локальной машине все грузит нормально, сколько бы строк не было. Если удалить всю инфу из CSV файла, которая идет после 588 строки добавит нормально, а вот следующая строка дает сбой. Еще получается после этого вся таблица пустая, т.е. скрипт вообще не чего не записывает. | |
|
|
|
|
|
|
|
для: magic
(23.03.2010 в 23:23)
| | так Вы посмотрите, что у Вас там на этой 589й строке.
Чего гадать-то? | |
|
|
|
|
|
|
|
для: Trianon
(24.03.2010 в 01:26)
| | В чем все и дело, идут строки
979002;Провод жгут;3;14,89 Грн.;27,24 Грн.
979003;Провод жгут;4;;25,31 Грн.
979006;Провод жгут;8;14,89 Грн.;27,24 Грн.
979008;Провод жгут;10;14,89 Грн.;27,24 Грн.
979009;Провод жгут;1;;27,24 Грн.
979010;Провод жгут;9;14,89 Грн.;27,24 Грн.
979011;Провод жгут;9;20,18 Грн.;37,06 Грн.
979012;Провод жгут;4;20,18 Грн.;37,06 Грн.
979013;Провод жгут;10;14,89 Грн.;27,24 Грн.
979016;Провод жгут;11;;37,06 Грн.
|
их таких 7000-8000.
Я удалял эту строку (589) в CSV файле, естественно нижняя строка подтягивается вверх и все равно выдает ошибку, вот если удалить все после 588 строки все работает.
я немного конечно модифицировал код, но я не думаю чтобы он мог повлиять. Дело в том что на локале работает, а вот на хостенге такая муть получается.
<?php
if(!empty($_POST['send']))
{
// блок для заполнения формы
$csv_file=$_FILES['filename']['tmp_name'];
if(!empty($_FILES['filename']['tmp_name']))
{
$start = microtime(1);
require_once("incl/connect.php");
// Функция экранирования переменных
function quote_smart($value)
{
// если magic_quotes_gpc включена - используем stripslashes
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// Если переменная - число, то экранировать её не нужно, если нет - то окружаем её кавычками, и экранируем
if (!is_numeric($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}
$id='0';
$query='';
$newline="INSERT INTO price VALUES";
mysql_query('TRUNCATE TABLE price');
$fp=fopen($csv_file, "r");
while($data=fgetcsv($fp, 1000, "\t"))
{
list($num, $name, $col, $pr_opt, $pr_roz) = $data;
$num=quote_smart($num);
$name=quote_smart($name);
$col=quote_smart($col);
$pr_opt=str_replace(',', '.', quote_smart($pr_opt));
$pr_roz=str_replace(',', '.', quote_smart($pr_roz));
$query.="$newline ($id, $num, $name, $col, $pr_opt, $pr_roz)";
$newline = ',';
}
fclose($fp);
if (mysql_query($query)) { echo "Прайс обновлен <br>"; }
else { exit(mysql_error()); }
$insert = microtime(1);
echo "Время затраченое на обновление ≈ ";
echo $insert-$start." с.";
echo "<HTML><HEAD><META HTTP-EQUIV='Refresh' CONTENT='10; URL=$_SERVER[PHP_SELF]'></HEAD></HTML>";
}
else { echo "Проверьте путь к указанному адресу"; }
}
?>
|
| |
|
|
|
|
|
|
|
для: magic
(24.03.2010 в 11:01)
| | 1. Что за чушь у Вас там с этим quote_smart?
C каких гвоздей Вы решили, что результат fgetcsv зависим от magic_quotes?
2. Возможно, у Вас переполняется предельный размер пакета SQL-запроса.
Совсем необязательно класть все строки в один запрос.
Наверное имеет смысл формировать запросы пакетами строк по двести-триста.
Тогда до 588 будет двукратный резерв.
Можно даже контролировать размер запроса при формировании.
Ограничиться 588 строками, посмотреть размер запроса, сравнить с предельным размером пакета запроса сервера.
Если похожи - опереться на эту зависимость (с некоторым допуском в минус, понятное дело) | |
|
|
|
|
|
|
|
для: Trianon
(24.03.2010 в 11:42)
| |
1. Что за чушь у Вас там с этим quote_smart?
C каких гвоздей Вы решили, что результат fgetcsv зависим от magic_quotes?
|
Данные получаемые от пользователей, могут сунуть туда что-то не хорошое, вот и экранирую. А у Вас зачем применяется
<?php $name = "'".mysql_real_escape_string($name)."'"; ?>
| в коде выше.
2. Возможно, у Вас переполняется предельный размер пакета SQL-запроса.
Совсем необязательно класть все строки в один запрос.
Наверное имеет смысл формировать запросы пакетами строк по двести-триста.
Тогда до 588 будет двукратный резерв.
Можно даже контролировать размер запроса при формировании.
Ограничиться 588 строками, посмотреть размер запроса, сравнить с предельным размером пакета запроса сервера.
Если похожи - опереться на эту зависимость (с некоторым допуском в минус, понятное дело)
|
А второй момент я не понял. Как можно сформировать запросы и контролировать? При помощи каких функций? | |
|
|
|
|
|
|
|
для: magic
(24.03.2010 в 15:27)
| | >>1. Что за чушь у Вас там с этим quote_smart?
>>C каких гвоздей Вы решили, что результат fgetcsv зависим от magic_quotes?[/code]
>Данные получаемые от пользователей, могут сунуть туда что-то не хорошое, вот и экранирую.
На вопрос ответьте, пожалуйста.
quote_smart опирается на состояние magic_quotes в этот момент и на этой машине (где php).
Данные взяты из csv-файла, полученного бог знает когда и откуда.
Почему Вы считаете, что данные, получаемые от пользователей нужно исправлять в зависимости от состояния magic quotes на этой машине и в этот момент времени?
>А у Вас зачем применяется
<?php $name = "'".mysql_real_escape_string($name)."'"; ?>
| в коде выше.
У меня эта функция применяется потому, что таковы правила формирования литеральных констант языка MySQL. А не потому что я боюсь, что кто-то кому-то что-то присунет, и неважно, хорошее или нет.
>>2. Возможно, у Вас переполняется предельный размер пакета SQL-запроса.
>>Совсем необязательно класть все строки в один запрос.
>>Наверное имеет смысл формировать запросы пакетами строк по двести-триста.
>>Тогда до 588 будет двукратный резерв.
>>
>>Можно даже контролировать размер запроса при формировании.
>>Ограничиться 588 строками, посмотреть размер запроса, сравнить с предельным размером пакета запроса сервера.
>>Если похожи - опереться на эту зависимость (с некоторым допуском в минус, понятное дело)[/code]
>>А второй момент я не понял. Как можно сформировать запросы и контролировать?
>При помощи каких функций?
Вы всё в этой жизни делаете при помощи функций?
Окей.
При помощи strlen() , mysql_query() и mysql_result() | |
|
|
|
|