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

Форум MySQL

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

 

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

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

тема: Составление запроса INSERT . ON DUPLICATE KEY
 
 автор: Владимир55   (10.11.2012 в 23:29)   письмо автору
199 байт
 
 

Для составления запроса используется вот такой код:

<?php
         $query 
"INSERT INTO kattov (producer, artikul, name_tov, cena, kol)" chr(13).chr(10) .
    
"VALUES" chr(13).chr(10);

    for (
$i 1$i count ($m_prise); $i++)
    {
        unset(
$m_str); // Удаление массива
        
$m_str explode(";"$m_prise[$i]);

        
$producer $m_str[0];
        
$artikul  $m_str[1];
        
$name_tov $m_str[2];
        
$cena     $m_str[3];
        
$kol      $m_str[4];

        
$producer iconv('cp1251''utf-8'$producer);
        
$name_tov iconv('cp1251''utf-8'$name_tov);

        
$query .= chr(9) . "('$producer', '$artikul', '$name_tov', '$cena', '$kol')" chr(13).chr(10);

    }


    
$query .= "ON DUPLICATE KEY UPDATE cena = VALUES(cena), kol = VALUES(kol);";

    
mysql_query($query);
    echo 
mysql_errno()." 175 : ".mysql_error()."<BR>"


И получаем диагностическое сообщение:

1064 175 : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('NIPPON MICRO FILTER CO', '1838290480', 'Наисма', '19510', '7') ('FAW',' at line 4

Во вложении прайс лист, из которого сформирован запрос.

Непонятно, в чем же ошибка? Нужна запятая после скобки?

  Ответить  
 
 автор: Sfinks   (11.11.2012 в 01:38)   письмо автору
 
   для: Владимир55   (10.11.2012 в 23:29)
 

Запятая нужна между добавляемыми строками.
Если память позволяет, проще сделать так:
<?php
    $rows 
= array();
    for (
$i 1$i count ($m_prise); $i++) 
    { 
       .................
       
$rows[] = "('$producer', '$artikul', '$name_tov', $cena$kol)";
    }
    
$query "INSERT INTO kattov (producer, artikul, name_tov, cena, kol)\n"
           
"VALUES\n"
           
implode",\n"$rows )."\n"
           
"ON DUPLICATE KEY UPDATE cena = VALUES(cena), kol = VALUES(kol);"
    
............
и для цены и количества кавычки не нужны. Лишние потери на преобразовании мускулом переданной строки в целое число.

  Ответить  
 
 автор: Владимир55   (11.11.2012 в 10:16)   письмо автору
 
   для: Sfinks   (11.11.2012 в 01:38)
 

Что-то здесь другое... Делаю так:

<?php
    mysql_query
("INSERT INTO kattov (producer, artikul, name_tov, cena, kol)
VALUES
    ('Kayaba Industry', '1520647485', 'Кларион', '10350', '7'),
    ('NIPPON MICRO FILTER CO', '1838290480', 'Наисма', '19510', '7'),
    ('FAW', '140922715', 'Медопраптизол', '12050', '4'),
ON DUPLICATE KEY UPDATE cena = VALUES(cena), kol = VALUES(kol)"
);

    echo 
mysql_errno()." 155 : ".mysql_error()."<BR>";


Получаю сообщение:

1064 155 : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON DUPLICATE KEY UPDATE cena = VALUES(cena), kol = VALUES(kol)' at line 6

  Ответить  
 
 автор: Sfinks   (11.11.2012 в 11:46)   письмо автору
 
   для: Владимир55   (11.11.2012 в 10:16)
 

Это не здесь другое, а УЖЕ другое =)
Теперь перед ON запятая не нужна.
Я поэтому и не стал вам писать что-то вроде
...
$query .= chr(9) . "('$producer', '$artikul', '$name_tov', '$cena', '$kol')," . chr(13).chr(10);
...
, а написал через implode(), чтоб этой лишней запятой не было.
Иначе нужно в цикле отслеживать количество проходов и в последнем круге не добавлять запятую.

Да, и пропускайте
        $producer = $m_str[0]; 
        $artikul  = $m_str[1]; 
        $name_tov = $m_str[2]; 
        $cena     = $m_str[3]; 
        $kol      = $m_str[4];
через mysql_real_escape_string() и intval(). А то еще ошибки могут повылазить.

  Ответить  
 
 автор: Владимир55   (11.11.2012 в 13:29)   письмо автору
342 байт
 
   для: Sfinks   (11.11.2012 в 11:46)
 

Спасибо, теперь сообщений об ошибках нет!

Сформированный запрос я сохранил в файле; файл во вложении. В нем все нормально?

И еще такой вопрос: а можно ли получить отчет об исполнении запроса? Чтобы узнать, сколько записей добавилось, а сколько обновилось? mysql выдает такую информацию?

==========
mysql_real_escape_string() и intval() я не стал использовать, поскольку в предшествующем контроле из текста удаляю одиночные кавычки, а в полях цены и количества контролируется отсутствие иных знаков, нежели цифры.

Или этого недостаточно?

  Ответить  
 
 автор: Владимир55   (11.11.2012 в 17:38)   письмо автору
 
   для: Владимир55   (11.11.2012 в 13:29)
 

Рано я обрадовался...

Тестовая страница содержит этот код:
    mysql_query("INSERT INTO kattov (producer, artikul, name_tov, cena, kol)
VALUES
    ('Kayaba Industry', '1520647485', 'Klaroin', '10350', '7'),
    ('NIPPON MICRO FILTER CO', '1838290480', 'Naosma', '19510', '7'),
    ('FAW', '140922715', 'Retil', '12050', '4')
ON DUPLICATE KEY UPDATE cena = VALUES(cena), kol = VALUES(kol)");

     echo mysql_errno()." 155 : ".mysql_error()."<BR>";


Я эту страницу открываю на сервере и в базу заносится три строки.

Обновляю страницу - все строки заносятся повторно.

И сколько раз я ее обновляю, столько раз и дублируются все три записи!

Разве так должно работать?

  Ответить  
 
 автор: Sfinks   (11.11.2012 в 18:08)   письмо автору
 
   для: Владимир55   (11.11.2012 в 17:38)
 

> Или этого недостаточно?
Достаточно.

> В нем все нормально?
.......
> ('FAW', '140922715', 'Retil', '12050', '4')
И все же уберите кавычки с целочисленных полей, чтоб было
('FAW', '140922715', 'Retil', 12050, 4)


> И сколько раз я ее обновляю, столько раз и дублируются все три записи!
А вы добавили составной уникальный индекс на первые 3 поля?
ALTER TABLE kattov ADD UNIQUE ( producer, artikul, name_tov );


> можно ли получить отчет об исполнении запроса? Чтобы узнать, сколько записей добавилось, а сколько обновилось?
На сколько я помню, PMA (если вы будете добавлять через него) сообщает сколько записей добавлено. Следовательно (сколько добавляли)-(сколько добавлено)=(сколько обновлено).
В крайнем случае, если и не сообщает, посмотрите количество строк до импорта и количество после - получите сколько добавлено.

  Ответить  
 
 автор: Владимир55   (11.11.2012 в 19:25)   письмо автору
65.3 Кб
 
   для: Sfinks   (11.11.2012 в 18:08)
 

Количество импортированных товаров вычислить-то несложно, но я предположил, что, может быть, MySQL сам выводит сообщение о результатах по аналогии с тем, как он сообщает об ошибке, если она есть (что-нибудь вместо mysql_errno).

"А вы добавили составной уникальный индекс на первые 3 поля?"

Я упустил из вида, что ON DUPLICATE KEY UPDATE работает только для столбцов с индексом UNIQUE или для PRIMARY ID. К тому же, название товара имело поле типа ТЕХТ, что не позволяло получить UNIQUE - пришлось поле изменить.

Сейчас Ваш запрос прошел. Во вложении типы полей. Все нормально? Я-то предположил, что появится дополнительное поле UNIQUE...

Можно UNIQUE формировать непосредственно при создании таблицы?


<?php
        $query 
"CREATE TABLE kattov
        (
              id         INT     (11) NOT NULL AUTO_INCREMENT,
              producer   VARCHAR (60) CHARACTER SET utf8,
              artikul    VARCHAR (40),
              name_tov   VARCHAR (200)  CHARACTER SET utf8,
             cena       INT     (6),
             kol        INT     (6),
             GUID       VARCHAR (40),
              PRIMARY KEY(id)
        ) ENGINE=MyISAM CHARACTER SET utf8"
;
        
mysql_query($query);  

  Ответить  
 
 автор: Sfinks   (11.11.2012 в 19:56)   письмо автору
 
   для: Владимир55   (11.11.2012 в 19:25)
 

Хм... А я вот про max_key_length только сейчас узнал =)

> Можно UNIQUE формировать непосредственно при создании таблицы?
Формировать может и можно, но требуемого эффекта вы не добьетесь, т.к. GUID будет всегда уникальным для каждой строки и обновления происходить не будет. Будут сплошные инсерты.

Возможен такой выход:
Добавить в существующую таблицу поле HASH:
ALTER TABLE kattov ADD `hash` CHAR( 32 ) NOT NULL

Заполнить это поле для существующих строк:
UPDATE kattov SET hash = md5(concat_ws('-delimiter-',producer,artikul,name_tov))

Добавить на него уникальный индекс:
ALTER TABLE kattov ADD UNIQUE( `hash`);

И поправить INSERT запрос:
<?php
  
.........
  
$rows[] = "('$producer', '$artikul', '$name_tov', $cena$kol, '".md5($producer.'-delimiter-'.$artikul.'-delimiter-'.$name_tov)."')";
  ........
  
$query "INSERT INTO kattov (producer, artikul, name_tov, cena, kol, hash)\n" 
         
"VALUES\n" 
         
implode",\n"$rows )."\n" 
         
"ON DUPLICATE KEY UPDATE cena = VALUES(cena), kol = VALUES(kol);

Получается у нас уникальное поле - хеш конкатенации 3ех полей, которые должны быть уникальны, соедененных через строку "-delimiter-".

А после импорта поле HASH можно и удалить.

  Ответить  
 
 автор: Владимир55   (11.11.2012 в 20:22)   письмо автору
 
   для: Sfinks   (11.11.2012 в 19:56)
 

Спасибо! ОЧЕНЬ интересная получилась тема!

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

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