Как узнать, была ли добавлена или обновлена строка «при обновлении дублированного ключа»?

У нас есть база данных, которая обновляется каждый день в полночь с помощью cronjob, мы получаем новые данные из внешнего XML.

То, что мы делаем, это то, что мы вставляем все новое содержимое, и в случае наличия дублированного ключа мы обновляем это поле.

INSERT INTO table (id, col1, col2, col3)
values (id_value, val1, val2, val3),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
ON DUPLICATE KEY UPDATE 
col1 = VALUES (col1), 
col2 = VALUES (col2), 
col3 = VALUES (col3);

Что мы хотим знать, так это то, какие строки были фактически вставлены, то есть мы хотим получить список новых элементов. есть ли запрос, который может вернуть новые вставки? В основном нам необходимо получить все новые идентификаторы, а не количество новых вставок.

Спасибо

Ответы на вопрос(4)

Решение Вопроса

Добавитьupdate_count INT NOT NULL DEFAULT 1 столбец и измените ваш запрос:

INSERT
INTO    table (id, col1, col2, col3)
VALUES
(id_value, val1, val2, val3),
(id_value, val1, val2, val3,),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
ON DUPLICATE KEY
UPDATE 
        col1 = VALUES (col1), 
        col2 = VALUES (col2), 
        col3 = VALUES (col3),
        update_count = update_count + 1;

Вы также можете увеличить его вBEFORE UPDATE триггер, который позволит вам сохранить запрос как есть.

 multimediaxp10 июн. 2012 г., 01:55
Спасибо Quassnoi, отличная идея, я использовал новую колонку под названием udpated и применил вашу идею с другим подходом, который мне действительно помог, пожалуйста, просмотрите ваш ответ на предмет изменений, которые я сделал, и дайте мне некоторую обратную связь. Это сработало отлично, спасибо.

Я могу сказать, как я сделал в PHP:

1) Простой запрос SELECT MAX (id) и запомните его до $ max_id из таблицы перед вставкой при дублировании.

2) Затем во время процесса обновления собирать идентификаторы затронутых строк (без новых или существующих материалов): $ ids [] = mysql_insert_id ();

3) Тогда $ insert_rows = max ($ ids) - $ max_id;

4) Обновлены строки = количество ($ ids_srt) - $ insert_rows

$max_id = mysql_query("SELECT MAX(id) from table");
$max_id = mysql_result($max_id, 0);

// !!! prepare here 'insert on duplicate' query in a cycle

$result=mysql_query($query);
$ids[] = mysql_insert_id();

// finish inserting and collecting affected ids and close cycle

$inserted_rows = max($ids)- $max_id;
$updated_rows = count($ids)- $inserted_rows

Добавьте поле временной метки в таблицу и установите для него значение по умолчаниюcurrent_timestamp, но не установленON UPDATE CURRENT_TIMESTAMP, Таким образом, если вы знаете время выполнения вашего задания cron, вы можете запросить все строки, которые были добавлены в это время или после него, но до следующего задания cron или до времени окончания, которое вы точно знаете, что cron завершил ,

Alter table your_table add column create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP следует обновить поле create_time автоматически только для вставок, а не для обновлений.

Если вы читаете наMySQL документация:

With a DEFAULT clause but no ON UPDATE CURRENT_TIMESTAMP clause, the column has the given default value and is not automatically updated to the current timestamp.

The default depends on whether the DEFAULT clause specifies CURRENT_TIMESTAMP or a constant value. With CURRENT_TIMESTAMP, the default is the current timestamp.

Итак, чтобы подвести итог, запрос какSELECT id from your_table where create_timestamp >= $cron_1_time and create_timestamp < $cron_2_time; должен дать вам то, что вы ищете. Конечно, все зависит от того, знаете ли вы приблизительно, когда выполняются задания cron и как долго.

Вы можете получить эту информацию во время вставки / обновления, изучив количество затронутых строк в наборе результатов.

MySQLдокументация состояния:

With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row and 2 if an existing row is updated.

Вам нужно будет объединить ROW_COUNT с LAST_INSERT_ID, чтобы получить свой ответ и вставлять по одной строке за раз.

 22 мая 2012 г., 22:14
Это помогает установитьhow many строки были вставлены против обновленных, но не которые были какие ...
 22 мая 2012 г., 22:26
@ EddyXP, вам нужно объединить ROW_COUNT с LAST_INSERT_ID, чтобы получить ответ и вставлять по одной строке за раз.
 multimediaxp22 мая 2012 г., 22:16
Да, мы думали об этом, но мне нужно знать первичный ключ вставленных строк, а не количество или количество вставленных строк.
 07 окт. 2014 г., 18:30
Имейте в виду, что если обновление произойдет, но с теми же предыдущими данными, строки с ошибками будут давать 0.

Ваш ответ на вопрос