Подтвердить что ты не робот

Как узнать, была ли добавлена ​​или обновлена ​​строка при использовании "при повторном обновлении ключа"?

У нас есть база данных, которая ежедневно обновляется в полночь с помощью 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);

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

Спасибо

4b9b3361

Ответ 1

Добавьте столбец 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, который позволит вам сохранить запрос как есть.

Ответ 2

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

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

С ON DUPLICATE KEY UPDATE значение затронутых строк в строке равно 1, если строка вставляется как новая строка и 2, если обновляется существующая строка.

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

Ответ 3

Добавьте поле таблицы времени в таблицу и установите его значение по умолчанию 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:

С условием DEFAULT, но без предложения ON UPDATE CURRENT_TIMESTAMP, столбец имеет заданное значение по умолчанию и не обновляется автоматически до текущая временная метка.

Значение по умолчанию зависит от того, указывает ли предложение DEFAULT CURRENT_TIMESTAMP или постоянное значение. С помощью CURRENT_TIMESTAMP default - текущая временная метка.

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

Ответ 4

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

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

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

3) Затем $insert_rows = max ($ ids) - $max_id;

4) Обновлены строки = count ($ ids_srt) - $inserted_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