[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: ON DUPLICATE KEY UPDATE
pr0fun
Добрый вечер, господа!

Делаю загрузку данных из csv в mysql.

Сделал следующее:
$query = "insert into $databasetable values('$linemysql');";
Загружает, все отлично.
Но столкнулся с тем, что при повторной загрузке этого же файла но с другими данными, происходит не обновление таблицы, а загрузка новых записей.
Мне это не нужно, полез в поисковики, нашел вот эту вешь ON DUPLICATE KEY UPDATE.
Применил у себя в коде, не пашет(не обновляет).
Выглядит оно вот так:
$query = "INSERT INTO $databasetable (`Message_ID`, `Name`, `Price`) VALUES ('$linemysql') ON DUPLICATE KEY UPDATE `Name`=VALUES(`Name`),`Price`=VALUES(`Price`)";

Где:
$databasetable - название таблицы в БД
$linemysql - массив строк кот-е берутся из файла .csv

Что у меня не так, господа?



Спустя 3 минуты, 39 секунд (4.04.2011 - 19:09) Trianon написал(а):
Что не так?
Вы не контролируете ошибки исполнения запроса.
Ну и не приводите сам запрос.

Спустя 5 минут, 8 секунд (4.04.2011 - 19:14) pr0fun написал(а):
Column count doesn't match value count at row 1
Количество столбцов не совпадает с количеством значений в строке 1

В смысле я не привожу запрос?

Спустя 6 минут, 46 секунд (4.04.2011 - 19:20) Trianon написал(а):
Вот именно.
Число заявленных колонок 3 : (`Message_ID`, `Name`, `Price`)
а значение в добавляеой строке всего одно : ('$linemysql')
Пожалуй проблема видна и без полного текста запроса.


В прямом. Запрос - это то, что видно по echo $query;
А пока у Вас лишь некий код, который этот запрос формирует.


Спустя 5 минут, 47 секунд (4.04.2011 - 19:26) pr0fun написал(а):
Извините, я понял о чем вы.
Значит так, это таблица:

[b]Message_ID Name Price
Name 1 5600
Name 2 3278
Name 3 1500
[/b]

Это сам запрос

INSERT INTO test2 (`NULL`, `Name`, `Price`) VALUES ('Message_ID','Name','Price') ON DUPLICATE KEY UPDATE `Name`=VALUES(`Name`),`Price`=VALUES(`Price`)
INSERT INTO test2 (`NULL`, `Name`, `Price`) VALUES ('','Name 1','5600') ON DUPLICATE KEY UPDATE `Name`=VALUES(`Name`),`Price`=VALUES(`Price`)
INSERT INTO test2 (`NULL`, `Name`, `Price`) VALUES ('','Name 2 test test','3278') ON DUPLICATE KEY UPDATE `Name`=VALUES(`Name`),`Price`=VALUES(`Price`)
INSERT INTO test2 (`NULL`, `Name`, `Price`) VALUES ('','Name 3 ','1500') ON DUPLICATE KEY UPDATE `Name`=VALUES(`Name`),`Price`=VALUES(`Price`)
INSERT INTO test2 (`NULL`, `Name`, `Price`) VALUES ('') ON DUPLICATE KEY UPDATE `Name`=VALUES(`Name`),`Price`=VALUES(`Price`)


test test в Name2 это измененная строка.

Как нужно составить правильный запрос?
Спасибо, что уделяете мне время.

Спустя 5 минут, 51 секунда (4.04.2011 - 19:32) pr0fun написал(а):
$linemysql - это есть массив, туда грузятся значения из csv.


Вот так я его получаю
$linearray = array();
$linemysql = implode("','",$linearray);

Спустя 13 минут, 14 секунд (4.04.2011 - 19:45) Trianon написал(а):
INSERT INTO test2 (`NULL`,
Это как?

Далее.
VALUES ('Message_ID','Name','Price')
зачем грузить заголовок?


Далее.
Цитата
Вот так я его получаю
$linearray = array();
$linemysql = implode("','",$linearray);


Так не выйдет.
придется Вам каждое значение в строке отдельно вытащить,
отдельно привести к числовому виду,
либо наоборот - заэкранировать (mysql_real_escape_string) и обрамить апострофами,
и лишь после этого каждое из значений подставить в список (благо он у Вас всего из трех полей. )

Кстати, совсем необязательно выполнять по запросу на каждую строку.
INSERT может быть и мультистрочным.
проверить

Спустя 2 минуты, 23 секунды (4.04.2011 - 19:48) T1grOK написал(а):
Не вижу поля первичного ключа.
Работать с дубликатом так:

INSERT INTO test2 (`id`, `Name`, `Price`) VALUES ('Message_ID','Name','Price') ON DUPLICATE KEY UPDATE `Name`=`Name`, `Price`=`Price`

В случае если такого ид нету выполнится левая часть(относительно ON) и будет добавлена новая запись, иначе выполнится правая часть и будет заапдейтена запись, ид которой совпадает.

Спустя 12 минут, 55 секунд (4.04.2011 - 20:01) Trianon написал(а):
T1grOK

На Вашем месте я не стал бы делать такие скоропалительные выводы.
Событие ON DUPLICATE KEYS фиксируется не столько по первичному ключу, сколько по уникальному индексу, коим этот первичный ключ в частности является.

Какая структура у таблицы, тредстартер нам так и не показал, какие индексы на ней ключи и расставлены - мы можем лишь догадываться.
Может у него Name - как unique объявлено.

Спустя 55 минут, 20 секунд (4.04.2011 - 20:56) Snus написал(а):
Цитата (T1grOK @ 4.04.2011 - 16:48)
INSERT INTO test2 (`id`, `Name`, `Price`) VALUES ('Message_ID','Name','Price') ON DUPLICATE KEY UPDATE `Name`=`Name`, `Price`=`Price`

А зачем так делать вообще?
INSERT IGNORE INTO `test2` ...


Спустя 1 час, 13 минут, 5 секунд (4.04.2011 - 22:09) Guest написал(а):
unique - у меня Message_ID, его как-то надо объявить в запросе? Как?

Спустя 27 минут (4.04.2011 - 22:36) Trianon написал(а):
Snus
Оператор INSERT IGNORE, кто бы мог подумать, просто проигнорирует те строки, уникальные ключи которых уже присутствуют в таблице.
Очевидно, это не то, чего хочет достичь автор.

Я бы еще понял REPLACE INTO..

Спустя 16 часов, 40 минут, 16 секунд (5.04.2011 - 15:16) pr0fun написал(а):
Сделал так

INSERT INTO test2 (`Message_ID`, `Name`, `Price`) VALUES ('Message_ID','Name','Price') ON DUPLICATE KEY UPDATE `Name`=`Name`, `Price`=`Price`;


Все равно не обновляет (

Спустя 12 минут, 24 секунды (5.04.2011 - 15:29) Trianon написал(а):

Спустя 9 минут, 7 секунд (5.04.2011 - 15:38) pr0fun написал(а):
За ссылку спасибо, пошел на ту ветку.

Спустя 1 день, 1 час, 20 минут, 29 секунд (6.04.2011 - 16:58) pr0fun написал(а):
Нашел скриптик, для загрузки в базу CSV, сделал для своих нужд.
<?
$db_username="222"; //database user name
$db_password="222";//database password
$db_database="222"; //database name
$db_host="222";


mysql_connect($db_host,$db_username,$db_password);
@mysql_select_db($db_database) or die( "Unable to connect to database.");


$handle = fopen("test.csv", "r");
if ($handle)
{
$array = explode("\n", fread($handle, filesize("test.csv")));
}

$total_array = count($array);
$i = 0;

while($i < $total_array)
{
$data = explode(";", $array[$i]);
$sql = "insert into test2(Message_ID,Name,Price) values ('$data[0]','$data[1]','$data[2]') ON DUPLICATE KEY UPDATE `Message_ID`=`Message_ID`, `Name`=`Name`, `Price`=`Price`";
$result = mysql_query($sql) or die(mysql_error());

$i++;
}
echo "completed";
?>


Записи обновляются, ок!
Но почему-то после каждого обновления добавляются пустые записи!
AUTO_INCREMENT может как-то влиять?
Как с этим бороться?

Спустя 15 минут, 20 секунд (6.04.2011 - 17:14) Trianon написал(а):
Есть сильное подозрение, что в CSV-файле у Вас в первой строке отнюдь не данные.
И Вы не делаете усилий её пропустить.


Кстати, это довольно странно, что записи обновляются.
Согласно Вашему коду они обновляться не должны.
Должны лишь добавляться новые.

Спустя 8 минут, 7 секунд (6.04.2011 - 17:22) pr0fun написал(а):
user posted image
Вот так выглядит csv...

Спустя 7 минут, 30 секунд (6.04.2011 - 17:29) pr0fun написал(а):
А вот что в БД
user posted image

Спустя 1 минута, 42 секунды (6.04.2011 - 17:31) pr0fun написал(а):
И наконец структура БД
user posted image

Спустя 2 часа, 12 минут, 46 секунд (6.04.2011 - 19:44) Trianon написал(а):
cтроки 32700, 32698, 32696 и т.д. возникли, как я и предполагал, при обработке строки 1 Вашего CSV-файла.

строки 32699, 32697, 32695 и т.д. образовались из-за того, что при разбиении файла по "\n" в массиве возникла последняя - пустая строка, без полей, импорту которой Вы тоже никак не препятствуете.

Пожалуй, на этом с подсказками можно и остановиться.

Спустя 2 часа, 51 минута, 10 секунд (6.04.2011 - 22:35) Snus написал(а):
Цитата (Trianon @ 4.04.2011 - 19:36)
Оператор INSERT IGNORE, кто бы мог подумать, просто проигнорирует те строки, уникальные ключи которых уже присутствуют в таблице.

Я в курсе, просто T1grOK предложил такой вариант
Цитата (T1grOK @ 4.04.2011 - 16:48)
INSERT INTO test2 (`id`, `Name`, `Price`) VALUES ('Message_ID','Name','Price') ON DUPLICATE KEY UPDATE `Name`=`Name`, `Price`=`Price`
, что идентично IGNORE

Спустя 12 часов, 40 минут, 34 секунды (7.04.2011 - 11:15) pr0fun написал(а):
Цитата (Trianon @ 6.04.2011 - 16:44)
cтроки 32700, 32698, 32696 и т.д. возникли, как я и предполагал, при обработке строки 1 Вашего CSV-файла.

строки 32699, 32697, 32695 и т.д. образовались из-за того, что при разбиении файла по "\n" в массиве возникла последняя - пустая строка, без полей, импорту которой Вы тоже никак не препятствуете.

Пожалуй, на этом с подсказками можно и остановиться.

Подскажите пожалуйста, как препятствовать импорту пустых строк в моём случае, к сожалению не знаю как это делать.

Спустя 44 минуты, 13 секунд (7.04.2011 - 12:00) Trianon написал(а):
Цитата
$data = explode(";", $array[$i]);



$data = explode(";", $array[$i]);
if($data[0] == 'Message_ID' || count($data) <3)
continue;

Спустя 2 часа, 52 минуты, 52 секунды (7.04.2011 - 14:52) pr0fun написал(а):
Импорт пустых строк обрубает. Trianon, спасибо!
Но вот с обновлением что-то не так...
Удаляю записи, потом загружаю данные из csv, в базе они появились, далее, загружаю сsv с другими данными, ну там имя поменял или цену, обновления в базе нет.

Сейчас у меня вот такв скрипте:
$query = "INSERT INTO test2 VALUES ('$data[0]','$data[1]','$data[2]') ON DUPLICATE KEY UPDATE `Message_ID`=`Message_ID`, `Name`=`Name`, `Price`=`Price`";


Я ничего не напутал?

Спустя 20 минут, 3 секунды (7.04.2011 - 15:13) pr0fun написал(а):
Все, получилось! Все обновилось!

Спустя 2 минуты, 50 секунд (7.04.2011 - 15:15) pr0fun написал(а):
Вот как надо было:


$query = "INSERT INTO test2(Message_ID,Name,Price) VALUES ('$data[0]','$data[1]','$data[2]')
ON DUPLICATE KEY UPDATE `Message_ID`=VALUES(`Message_ID`),`Name`= VALUES(`Name`),
`Price` = VALUES(`Price`)"
;

Спустя 4 часа, 2 минуты, 34 секунды (7.04.2011 - 19:18) Trianon написал(а):
Цитата
Message_ID`=VALUES(`Message_ID`)

чушь
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.