Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Load data, функция не разрешена
 
 автор: magic   (14.03.2010 в 15:25)   письмо автору
 
 

Подскажите, как реализовать загрузку exсel файла в БД? Функция LOAD DATA запрещена на хосте. Выдает вот такое сообщение The used command is not allowed with this MySQL version, вычетал в инете. Проблема в том что файлы большие, прайсы где-то по 10000-30000 найменований. Как мне кажется, не очень удачно будет проходить INSERT-ом каждое значение. Надо типа админки, чтоб каждый мог загружать свой прайс. В PhpMyAdmin пускать всех нельзя естественно. Как быть? Заранее спасибо.

  Ответить  
 
 автор: magic   (15.03.2010 в 10:39)   письмо автору
 
   для: magic   (14.03.2010 в 15:25)
 

.

  Ответить  
 
 автор: Trianon   (15.03.2010 в 13:23)   письмо автору
 
   для: magic   (14.03.2010 в 15:25)
 

Вам сообщили - в этой версии MySQL эту команду не применить.
Вы же даже эту самую версию не привели.
Что Вы ждете?

И таки существуют многострочные INSERTs. Совсем неолбязательно на каждую строку клепать отдельный запрос.

  Ответить  
 
 автор: magic   (15.03.2010 в 20:16)   письмо автору
 
   для: Trianon   (15.03.2010 в 13:23)
 

На хосте phpinfo() показывает версия 5.0.81, у меня локально 5.0.27, но у меня все нормально. Ну я так понял что это сообщение выскакивает когда запрещают использование load data. По крайнер мере так было написано на сайте http://php.su/mysql/manual/?page=LOAD_DATA_LOCAL. Только я там не понял насчет версий.

  Ответить  
 
 автор: Trianon   (15.03.2010 в 23:58)   письмо автору
 
   для: magic   (15.03.2010 в 20:16)
 

Что ж, прошу прощения, возможно на счет блокировки Вы и правы.
Тогда придется таки применять многострочный INSERT .

  Ответить  
 
 автор: magic   (16.03.2010 в 11:28)   письмо автору
 
   для: Trianon   (15.03.2010 в 23:58)
 

Я понял, ну что тогда придется многострочный INSERT применять. Теперь возникает другой вопрос. В БД есть шесть столбцов, в файле тоже есть шесть столбцов с данными. Как организовать заполнение INSERTa из файла что бы получилось так INSERT INTO tb1 VALUES (1, 'процессоры'), (2, 'видеокарты'), (3, 'мат.платы'), или что то подобное. Я думаю, циклом заполнять массив, считывать строку с разделителями до конца строки. Хотел бы узнать в правильном направлении я двигаюсь. Спасибо

  Ответить  
 
 автор: Trianon   (16.03.2010 в 11:33)   письмо автору
 
   для: magic   (16.03.2010 в 11:28)
 

http://softtime.ru/forum/read.php?id_forum=3&id_theme=18535

  Ответить  
 
 автор: magic   (17.03.2010 в 15:25)   письмо автору
 
   для: 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($fp1000";"))
{
  
$cnt=count($data);
  for(
$i=0$i<$cnt$i++)
  {
   echo 
$data[$i];
  } 
}
fclose($fp);
?>

  Ответить  
 
 автор: Trianon   (17.03.2010 в 15:57)   письмо автору
 
   для: magic   (17.03.2010 в 15:25)
 

Вы полагаете, на Ваш вопрос можно ответить что-то путное, не зная структуры данных ни CSV-таблицы ни SQL-таблицы?

  Ответить  
 
 автор: magic   (17.03.2010 в 16:20)   письмо автору
 
   для: 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($fp1000";")) 

  
$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 Грн.

  Ответить  
 
 автор: Trianon   (17.03.2010 в 16:45)   письмо автору
 
   для: 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($fp1000";")) 

  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 будет что-то адекватное требуемому.

  Ответить  
 
 автор: magic   (19.03.2010 в 12:22)   письмо автору
 
   для: Trianon   (17.03.2010 в 16:45)
 

Спасибо за помощь. Все работает. А для чего здесь приводится перевод строки в
$sql .= "$newline \r\n ($id, $name, $qty, $price_opt, $price_rozn)";

  Ответить  
 
 автор: Trianon   (19.03.2010 в 12:24)   письмо автору
 
   для: magic   (19.03.2010 в 12:22)
 

Судя по оформлению Ваших реплик в этой теме (а они все идут одной строкой), я не смогу Вам этого объяснить.

  Ответить  
 
 автор: magic   (19.03.2010 в 20:32)   письмо автору
 
   для: Trianon   (19.03.2010 в 12:24)
 

Ну как бы, что тут непонятного. Вы мне помогли со скриптом выше, все работает, спасибо. Там есть переменная $sql, я спросил для чего в ней применяется конец строки. Вот и все.

  Ответить  
 
 автор: magic   (23.03.2010 в 23:23)   письмо автору
 
   для: magic   (14.03.2010 в 15:25)
 

Кто подскажет, имеется проблема. Скрипт (тот который выше в этой теме) для загрузки БД работает, но почему то только если количество строк меньше 589. Если строк больше то выдает вот такую ошибку Illegal double '01E311115' value found during parsing. На локальной машине все грузит нормально, сколько бы строк не было. Если удалить всю инфу из CSV файла, которая идет после 588 строки добавит нормально, а вот следующая строка дает сбой. Еще получается после этого вся таблица пустая, т.е. скрипт вообще не чего не записывает.

  Ответить  
 
 автор: Trianon   (24.03.2010 в 01:26)   письмо автору
 
   для: magic   (23.03.2010 в 23:23)
 

так Вы посмотрите, что у Вас там на этой 589й строке.
Чего гадать-то?

  Ответить  
 
 автор: magic   (24.03.2010 в 11:01)   письмо автору
 
   для: 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($fp1000"\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 
"Время затраченое на обновление &asymp; ";
            echo 
$insert-$start." с.";
            echo 
"<HTML><HEAD><META HTTP-EQUIV='Refresh' CONTENT='10; URL=$_SERVER[PHP_SELF]'></HEAD></HTML>";
        }
        else { echo 
"Проверьте путь к указанному адресу"; }
    }
    
?>

  Ответить  
 
 автор: Trianon   (24.03.2010 в 11:42)   письмо автору
 
   для: magic   (24.03.2010 в 11:01)
 

1. Что за чушь у Вас там с этим quote_smart?
C каких гвоздей Вы решили, что результат fgetcsv зависим от magic_quotes?

2. Возможно, у Вас переполняется предельный размер пакета SQL-запроса.
Совсем необязательно класть все строки в один запрос.
Наверное имеет смысл формировать запросы пакетами строк по двести-триста.
Тогда до 588 будет двукратный резерв.

Можно даже контролировать размер запроса при формировании.
Ограничиться 588 строками, посмотреть размер запроса, сравнить с предельным размером пакета запроса сервера.
Если похожи - опереться на эту зависимость (с некоторым допуском в минус, понятное дело)

  Ответить  
 
 автор: magic   (24.03.2010 в 15:27)   письмо автору
 
   для: Trianon   (24.03.2010 в 11:42)
 

1. Что за чушь у Вас там с этим quote_smart? 
C каких гвоздей Вы решили, что результат fgetcsv зависим от magic_quotes?

Данные получаемые от пользователей, могут сунуть туда что-то не хорошое, вот и экранирую. А у Вас зачем применяется
<?php $name "'".mysql_real_escape_string($name)."'"?>
в коде выше.
2. Возможно, у Вас переполняется предельный размер пакета SQL-запроса.
Совсем необязательно класть все строки в один запрос.
Наверное имеет смысл формировать запросы пакетами строк по двести-триста. 
Тогда до 588 будет двукратный резерв.

Можно даже контролировать размер запроса при формировании. 
Ограничиться 588 строками, посмотреть размер запроса, сравнить с предельным размером пакета запроса сервера. 
Если похожи - опереться на эту зависимость (с некоторым допуском в минус, понятное дело)

А второй момент я не понял. Как можно сформировать запросы и контролировать? При помощи каких функций?

  Ответить  
 
 автор: Trianon   (24.03.2010 в 20:44)   письмо автору
 
   для: 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()

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования