MySql Таблиця Вставте, якщо не існує, іншим чином оновіть


105
UPDATE AggregatedData SET datenum="734152.979166667", 
Timestamp="2010-01-14 23:30:00.000" WHERE datenum="734152.979166667";

Він працює, якщо datenumіснує, але я хочу вставити ці дані як новий рядок, якщо такий datenumне існує.

ОНОВЛЕННЯ

datenum унікальний, але це не основний ключ


2
Чи унікальний "датен"? Ви можете використовувати INSERT ... ON DUPLICATE KEY UPDATE, якщо він є.
Яків

Відповіді:


143

Джай правильно, що ви повинні використовувати INSERT ... ON DUPLICATE KEY UPDATE.

Зауважте, що вам не потрібно включати datenum в пункт оновлення, оскільки це унікальний ключ, тому він не повинен змінюватися. Вам потрібно включити всі інші стовпці зі своєї таблиці. Ви можете використовувати цю VALUES()функцію, щоб переконатися, що належні значення використовуються під час оновлення інших стовпців.

Ось ваше оновлення, переписане за допомогою відповідного INSERT ... ON DUPLICATE KEY UPDATEсинтаксису для MySQL:

INSERT INTO AggregatedData (datenum,Timestamp)
VALUES ("734152.979166667","2010-01-14 23:30:00.000")
ON DUPLICATE KEY UPDATE 
  Timestamp=VALUES(Timestamp)

18
Будьте обережні при використанні INSERT ... ON DUPLICATE KEY UPDATE на таблицях проти таблиці, що містить більше одного унікального або первинного ключа. Взяте з документації на MySQL : Крім того, починаючи з MySQL 5.5.24, оператор INSERT ... ON DUPLICATE KEY UPDATE проти таблиці, що містить більше одного унікального або первинного ключа, також позначається як небезпечний. (Bug # 11765650, Bug # 58637) Bug 58637 опис bugs.mysql.com/bug.php?id=58637
широкосмуговий

1
Можливо, знадобиться створити UNIQUEобмеження Timestamp, використовуючиALTER TABLE AggregatedData ADD UNIQUE (Timestamp)
Avyakt

@broadband ви можете використовувати складений ключ, щоб уникнути цієї помилки
Kareem

16

Спробуйте скористатися цим :

Якщо ви вкажете ON DUPLICATE KEY UPDATE, і вставляється рядок , яка буде викликати повторюване значення в UNIQUE index orPRIMARY KEY , MySQL performs an [UPDATE`] ( http://dev.mysql.com/doc/refman/5.7/en/update.html ) старої рядки. ..

ON DUPLICATE KEY UPDATEРозділ може містити кілька призначень стовпців, розділених комами.

З ON DUPLICATE KEY UPDATE, значення рядків із зачіпаючими рядками для кожного рядка дорівнює 1, якщо рядок вставлено як новий рядок, 2, якщо існуючий рядок оновлюється, і 0, якщо для існуючого рядка встановлено його поточні значення. Якщо ви встановите CLIENT_FOUND_ROWSпрапор до mysql_real_connect()підключення до mysqld , значення рядків, на які впливає, дорівнює 1 (а не 0), якщо для існуючого рядка встановлено його поточні значення ...


Але моя датенія - не первинний ключ.
OHLÁLÁ

Тож у моєму випадку, що таке рішення, я спробував це, без будь-якого рішення: ВСТАВКА INTO forwind.aggregateddata (datenum, Timestamp, Min_F1_baro_20_) VALUES ('1', '2', '3') ON DUPLICATE KEY UPDATE datenum = кульбаба;
OHLÁLÁ

1
чи датен має бути унікальним? якщо так, то додайте до нього унікальний індекс (якщо він ще не доданий), тоді він спрацює. Зверніться до dev.mysql.com/doc/refman/5.1/uk/alter-table.html, як рекламувати UNIQUE індекси
Jai

тепер я визначив датену як унікальний, і він працює добре, дякую
OHLÁLÁ

1
Просто посилання, може дати відповідь.
Андрій

0

У мене виникла ситуація, коли мені потрібно було оновити або вставити в таблицю відповідно до двох полів (обидва зовнішні ключі), в яких я не міг встановити єдине обмеження (так ВСТАВКА ... НА ДУПЛІКАТИ КЛЮЧНОГО ОНОВЛЕННЯ не буде працювати). Ось що я закінчив:

replace into last_recogs (id, hasher_id, hash_id, last_recog) 
  select l.* from 
    (select id, hasher_id, hash_id, [new_value] from last_recogs 
     where hasher_id in (select id from hashers where name=[hasher_name])
     and hash_id in (select id from hashes where name=[hash_name]) 
     union 
     select 0, m.id, h.id, [new_value] 
     from hashers m cross join hashes h 
     where m.name=[hasher_name] 
     and h.name=[hash_name]) l 
  limit 1;

Цей приклад наводиться з однієї з моїх баз даних, вхідні параметри (два імені та номер) замінені на [hasher_name], [hash_name] та [new_value]. Вкладений SELECT ... LIMIT 1 витягує першу з наявних або нових записів (last_recogs.id є первинним ключем для автоматичного збільшення) і використовує це як введення значення в ЗАМІНУВАННЯ ДО.


ЗАМІНА завжди вставляє новий рядок! він просто видаляє оригінальний, вже існуючий!
jasie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.