2014-01-03 6 views
1

Если у меня есть таблица с 2 столбцами, что если я собираюсь обновить столбец в этой таблице, который создает повторяющиеся строки, эта таблица также имеет уникальное ограничение, существует ли какой-либо способ, если уникальная строка получить, когда я обновляю, я могу обработать эту строку?update row with duplicates value

+1

Оборонительная подход должен был бы проверить «был бы» дублей первым. – Flosculus

+0

@Flosculus Если я проверил таблицу, не было бы дубликатов, но может быть обновление будет создавать дубликаты. Посмотрите, что –

+0

Обновление не может его дублировать, уникальное ограничение предотвратит его, насколько я знаю. – Goikiu

ответ

0

Обычно добавление оператора SQL inline IF с некоторыми критериями и необязательной обработкой и самоподключение для обнаружения дублирования сделает то, что вы ищете. Истинный ответ будет специфичен для вашей структуры, но я приведу пример для таблицы с именем user с столбцом id, который является первичным ключом, и SSN, который имеет уникальное ограничение на него. Мы заполним его с 2 пользователей и обновить одну из них, чтобы дублировать первый в уникальной Ssn колонке»

CREATE TABLE `test`.`user` (
`id` INT NOT NULL, 
`SSN` VARCHAR(45) NULL, 
PRIMARY KEY (`id`), 
UNIQUE INDEX `ssn_UNIQUE` (`SSN` ASC)); 

INSERT INTO user VALUES (1, "1234567"), (2, ""); 

Как вы уже заметили, если я запускаю следующее сообщение, когда другой пользователь (где ID = 1 .) уже имеет ПЛА = «1234567», то мы не сделали никаких обновлений

UPDATE user SET SSN="1234567" WHERE id=2; 

ERROR 1062 (23000): Duplicate entry '1234567' for key 'ssn_UNIQUE' 

Однако рассмотрим следующие вместо:

UPDATE user u 
LEFT JOIN user AS u2 
    ON u2.SSN="1234567" 
SET u.SSN=IF(
    u2.id IS NOT NULL, 
    CONCAT(u2.SSN, "duplicates", u2.id, "onto", u.id), 
    "1234567") 
WHERE u.id=2; 

Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

В приведенном выше примере, следующие сценарии могут играть:

Если идентификатор пользователя = 1 уже имеет SSN = «1234567», и я бегу выше обновления, то результат будет:

SELECT * FROM test.user; 
+----+--------------------------+ 
| id | SSN      | 
+----+--------------------------+ 
| 2 | 1234567duplicates1onto2 | 
| 1 | 1234567     | 
+----+--------------------------+ 
2 rows in set (0.00 sec) 

Если я пытаюсь установить вместо «» вместо этого, и я запустить тот же выше обновления, то результат будет:

SELECT * FROM test.user; 
+----+----------+ 
| id | SSN  | 
+----+----------+ 
| 2 || 
| 1 | 1234567 | 
+----+----------+ 
2 rows in set (0.00 sec) 

Если бы я был 3-й пользователь, пользователь может возможно иметь значение «1234567duplicates2», если две другие пользователи имели попытки установить значение на «1234567 Аналогичным образом:

SELECT * FROM test.user; 
+----+-------------------------+ 
| id | SSN      | 
+----+-------------------------+ 
| 1 | 1234567     | 
| 2 | 1234567duplicates1onto2 | 
| 3 | 1234567duplicates1onto3 | 
+----+-------------------------+ 
3 rows in set (0.00 sec) 

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

Чтобы адаптировать эту технику, просто измените вывод встроенного IF на формулу, которую вы будете использовать для обработки, а критерии для JOIN должны быть чем угодно, чтобы обеспечить обнаружение дублирования.

http://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html