Моя программа получает список идентификаторов, некоторые из которых находятся в нашей системе, некоторые из которых не являются. Цель состоит в том, чтобы сделать запись в таблицу для идентификаторов, существующих в нашей системе, но игнорировать те, которые этого не делают.
Пример:
Incomming My System Inserted 555 583 583 583 599
Моя первоначальная мысль заключалась в том, чтобы использовать INSERT IGNORE
но список идентификаторов для проверки находится в таблице users, а строки вставляются в таблицу событий. Я также попробовал ограничение внешнего ключа, но INSERT IGNORE
не сработает молча с FK – он выдает ошибку, которая убивает любые последующие вставки.
Мой текущий угол атаки состоит в том, чтобы читать во всех идентификаторах таблицы пользователей на PHP и проверять идентификаторы на PHP перед попыткой вставить, но это кажется субоптимальным. Есть ли способ MySQL сделать это?
INSERT INTO your_id_table (ID) SELECT ID FROM my_system_table WHERE ID IN (list_of_ids)
Я надеюсь, что это ясно, с этим вам вообще не нужно делать никаких проверок, вы просто запускаете запрос и выполняете его.
Вы можете использовать оператор if (), который проверяет, существует ли значение в таблице пользователя перед вставкой.
if exists (select * from user where id = @id) begin /*insert*/ end else begin /*return a status message or insert in error table to track failed records*/ end
Это довольно уродливый способ сделать это, но он работает:
$ids = array( /* ids */ ); $ids = implode(',', $ids); $sql = 'SELECT `id` FROM `table` WHERE `id` IN ('.$ids.')'; $result = $db -> query($sql); $exists = $result -> fetch_all(); $doesntExist = array_diff($ids, $exists);
Вы можете попробовать:
INSERT INTO Inserted(id) VALUES SELECT id FROM Incoming WHERE id IN (SELECT id FROM My_System)
Это выбирает идентификаторы Incomming, которые также находятся в My_System, и вставляет их в Inserted.
Вы можете сделать что-то вроде этого:
INSERT INTO events (iduser) SELECT iduser FROM users WHERE iduser IN (1,2,3,4,5)
Этот запрос будет возвращать только идентификаторы пользователя, которые присутствуют в таблице, поэтому это должно сделать трюк.
Если у вас больше столбцов для вставки, это будет выглядеть примерно так:
$idsToInsert = "1,2,3,4,5,6"; $query = "INSERT INTO events (iduser, title) SELECT iduser, ".$title." FROM users WHERE iduser IN (".$idsToInsert.")";
И не забудьте очистить свой ввод, используя mysql_real_escape, вы также можете использовать параметризованный запрос s для этого.
Эта последняя часть запроса, которую вы должны генерировать динамически через PHP, но это не проблема
Ссылка Mysql для вставки в таблицу select from находится здесь: http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
Вы можете сделать это на PHP Code
$result = mysql_query("SELECT id FROM another_table WHERE id = '100'"); $number_of_rows = mysql_num_rows($result); if ($number_of_rows > 0) { // ID exist in other table }
FK производит ошибку, которая убивает любые последующие вставки
Почему это убивает следующие вставки? Вставляйте вставки один за другим, проверяйте ошибки mysql.
Это самое элегантное решение, о котором я могу думать:
INSERT INTO events (id) SELECT id FROM my_system ms LEFT JOIN incoming i ON i.id = ms.id WHERE i.id IS NOT NULL
Идея здесь заключается в том, что вы исключаете эти записи в таблице «Входящие», которые не имеют соответствующей записи в таблице my_system, потому что набор результатов будет нулевым для входящих идентификаторов.
Похоже, что некоторые другие люди уже придумали подобное решение! Надеюсь, это поможет, так или иначе.
Внутреннее соединение – самый чистый способ вытащить его
INSERT INTO events (id) SELECT incoming.id FROM my_system ms INNER JOIN incoming i USING (id);
Просто загрузите входящие идентификаторы во входящую таблицу. Кроме того, не забудьте указать id как ПЕРВИЧНЫЙ КЛЮЧ для обеих таблиц.
Просто делать:
insert into events (id, value1, value2, ...) select id, @value1, @value2, ... from users where id = @id
Таким образом, он будет вставляться только в том случае, если идентификатор уже существует в вашей таблице users
. Это предполагает, что значение id
уникально для каждой строки в таблице users
, но если бы оно не просто добавлялось distinct
после выбора, чтобы вставить только одну строку.