Вставить однозначно в таблицу MySQL без уникальных ключей - PullRequest
4 голосов
/ 27 июня 2011

Я хотел бы вставить данные в одну из моих таблиц MySQL уникально. То есть, если та же самая запись (все столбцы содержат одно и то же значение) уже существует в таблице, операция вставки должна быть отклонена. Это может быть легко сделано путем определения уникальных ключей и обработки предстоящей ошибки, но я не могу изменить структуру таблицы.

Я уверен, что есть простой способ поймать это даже в таблицах без уникальных ключей. Конечно, я могу вручную проверить наличие такой записи, используя оператор SELECT заранее, но могут быть одновременные случаи, которые изменяют мою таблицу в это время (между проверкой с помощью SELECT и фактической INSERT).

Я хотел бы выполнить проверку и операцию INSERT в одной команде SQL. Кто-нибудь может указать мне правильное направление?

Ответы [ 3 ]

5 голосов
/ 27 июня 2011

Предположим, что в вашей таблице 5 столбцов - col1, col2, col3, col4, col5. И предположим, что данные, соответствующие этим столбцам, которые вы пытаетесь вставить, находятся в переменных - $ col1, $ col2, $ col3, $ col4, $ col5 (я предполагаю, что PHP является вашим языком, но, пожалуйста, измените формат переменных согласно Ваша номенклатура).

Таким образом, ваша вставка может выглядеть следующим образом:

INSERT INTO `tableA` (`col1`, `col2`, `col3`, `col4`, `col5`)
SELECT $col1, $col2, $col3, $col4, $col5
FROM `tableA`
WHERE NOT EXISTS (SELECT 1
    FROM `tableA`
    WHERE `col1` = $col1
    AND `col2` = $col2
    AND `col3` = $col3
    AND `col4` = $col4
    AND `col5` = $col5);

Другая альтернатива может быть:

INSERT INTO `tableA` (`col1`, `col2`, `col3`, `col4`, `col5`)
SELECT $col1, $col2, $col3, $col4, $col5
FROM `tableA`
WHERE `col1` = $col1
AND `col2` = $col2
AND `col3` = $col3
AND `col4` = $col4
AND `col5` = $col5
HAVING COUNT(1) = 0;

Надеюсь, это поможет.

0 голосов
/ 27 июня 2011

Без уникального ключа единственный способ убедиться, что уникальные строки не допускают параллелизма записи в таблице (либо с их блокировкой, либо с использованием уровня изоляции с сериализацией)

0 голосов
/ 27 июня 2011

Вы можете использовать блокировку таблицы с запросом, и пока ваш запрос не завершит обработку, никакой другой процесс не изменит его.

Проверьте эту ссылку: http://www.mssqlcity.com/Articles/Adm/SQL70Locks.htm

а затем делай, как ты сказал «Такая запись заранее использует оператор SELECT, но могут быть параллельные экземпляры, которые тем временем изменяют мою таблицу (между проверкой с помощью SELECT и фактической INSERT).»

...