MySQL: вставить запись, если она не существует в таблице.
Я пытаюсь выполнить следующий запрос:
INSERT INTO table_listnames (name, address, tele)
VALUES ('Rupert', 'Somewhere', '022')
WHERE NOT EXISTS (
SELECT name FROM table_listnames WHERE name='value'
);
Но это возвращает ошибку. В принципе, я не хочу вставлять запись, если поле "имя" записи уже существует в другой записи - как проверить, уникально ли новое имя?
Ответы
Ответ 1
Я на самом деле не предлагаю, чтобы вы это делали, поскольку индекс UNIQUE
, предложенный Piskvor и другими, намного лучший способ сделать это, но вы действительно можете делать то, что вы пытаетесь:
CREATE TABLE `table_listnames` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`address` varchar(255) NOT NULL,
`tele` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Вставьте запись:
INSERT INTO table_listnames (name, address, tele)
SELECT * FROM (SELECT 'Rupert', 'Somewhere', '022') AS tmp
WHERE NOT EXISTS (
SELECT name FROM table_listnames WHERE name = 'Rupert'
) LIMIT 1;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
SELECT * FROM `table_listnames`;
+----+--------+-----------+------+
| id | name | address | tele |
+----+--------+-----------+------+
| 1 | Rupert | Somewhere | 022 |
+----+--------+-----------+------+
Попробуйте снова вставить одну и ту же запись:
INSERT INTO table_listnames (name, address, tele)
SELECT * FROM (SELECT 'Rupert', 'Somewhere', '022') AS tmp
WHERE NOT EXISTS (
SELECT name FROM table_listnames WHERE name = 'Rupert'
) LIMIT 1;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
+----+--------+-----------+------+
| id | name | address | tele |
+----+--------+-----------+------+
| 1 | Rupert | Somewhere | 022 |
+----+--------+-----------+------+
Вставьте другую запись:
INSERT INTO table_listnames (name, address, tele)
SELECT * FROM (SELECT 'John', 'Doe', '022') AS tmp
WHERE NOT EXISTS (
SELECT name FROM table_listnames WHERE name = 'John'
) LIMIT 1;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
SELECT * FROM `table_listnames`;
+----+--------+-----------+------+
| id | name | address | tele |
+----+--------+-----------+------+
| 1 | Rupert | Somewhere | 022 |
| 2 | John | Doe | 022 |
+----+--------+-----------+------+
И так далее...
Ответ 2
INSERT не позволяет WHERE
в синтаксисе.
Что вы можете сделать: создайте UNIQUE INDEX
в поле, которое должно быть уникальным (name
), затем используйте либо:
- normal
INSERT
(и обрабатывать ошибку, если имя уже существует)
-
INSERT IGNORE
(который будет терпеть неудачу вызывает предупреждение (вместо ошибки), если имя уже существует)
-
INSERT ... ON DUPLICATE KEY UPDATE
(который будет выполнять UPDATE
в конце, если имя уже существует, см. документацию)
Ответ 3
Работал:
INSERT INTO users (full_name, login, password)
SELECT 'Mahbub Tito','tito',SHA1('12345') FROM DUAL
WHERE NOT EXISTS
(SELECT login FROM users WHERE login='tito');
Ответ 4
MySQL предоставляет очень милые решения:
REPLACE INTO `table` VALUES (5, 'John', 'Doe', SHA1('password'));
Очень проста в использовании, так как вы объявили уникальный первичный ключ (здесь со значением 5).
Ответ 5
INSERT IGNORE INTO `mytable`
SET `field0` = '2',
`field1` = 12345,
`field2` = 12678;
Здесь запрос mysql, который вставляет записи, если не существует, и будет игнорировать существующие аналогичные записи.
----Untested----
Ответ 6
Если вы действительно не можете получить уникальный индекс в таблице, вы можете попробовать...
INSERT INTO table_listnames (name, address, tele)
SELECT 'Rupert', 'Somewhere', '022'
FROM some_other_table
WHERE NOT EXISTS (SELECT name
FROM table_listnames
WHERE name='Rupert')
LIMIT 1;
Ответ 7
Чтобы преодолеть подобную проблему, я сделал таблицу, которую я вставляю, чтобы иметь уникальный столбец. Используя ваш пример, при создании я бы хотел что-то вроде:
name VARCHAR(20),
UNIQUE (name)
а затем используйте следующий запрос при вставке в него:
INSERT IGNORE INTO train
set table_listnames='Rupert'
Ответ 8
Этот запрос работает хорошо:
INSERT INTO `user` ( `username` , `password` )
SELECT * FROM (SELECT 'ersks', md5( 'Nepal' )) AS tmp
WHERE NOT EXISTS (SELECT `username` FROM `user` WHERE `username` = 'ersks'
AND `password` = md5( 'Nepal' )) LIMIT 1
И вы можете создать таблицу, используя следующий запрос:
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`password` varchar(32) NOT NULL,
`status` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Примечание. Создайте таблицу, используя второй запрос, прежде чем пытаться использовать первый запрос.
Ответ 9
вы можете легко использовать следующий путь:
INSERT INTO ..... ON DUPLICATE KEY UPDATE ...
таким образом вы можете вставить любое новое необработанное, и если у вас есть повторяющиеся данные, замените определенный столбец (лучший столбец - временные метки). например:
CREATE TABLE IF NOT EXISTS Devices (
id INT(6) NOT NULL AUTO_INCREMENT,
unique_id VARCHAR(100) NOT NULL PRIMARY KEY,
created_at VARCHAR(100) NOT NULL,
UNIQUE KEY unique_id (unique_id),
UNIQUE KEY id (id)
)
CHARACTER SET utf8
COLLATE utf8_unicode_ci;
INSERT INTO Devices(unique_id, time)
VALUES('$device_id', '$current_time')
ON DUPLICATE KEY UPDATE time = '$current_time';
Ответ 10
Брайан Хупер:
Вы почти достигли точки, но у вас есть ошибка в вашем синтаксисе. Ваша вставка никогда не будет работать. Я тестировал свою базу данных и вот правильный ответ:
INSERT INTO podatki (datum,ura,meritev1,meritev1_sunki,impulzi1,meritev2,meritev2_sunki,impulzi2)
SELECT '$datum', '$ura', '$meritve1','$sunki1','$impulzi1','$meritve2','$sunki2','$impulzi2'
FROM dual
WHERE NOT EXISTS (SELECT datum,ura
FROM podatki
WHERE datum='$datum' and ura='$ura'
Я даю вам мой пример таблицы y. Вставка почти такая же, как писал Биан Хупер, за исключением того, что я помещаю select FROM DUAL ont из другой таблицы.
С уважением, Иван
Ответ 11
insert into customer_keyskill(customerID, keySkillID)
select 2,1 from dual
where not exists (
select customerID from customer_keyskill
where customerID = 2
and keySkillID = 1 )
Ответ 12
Вы вставляете, не обновляя результат.
Вы можете определить столбец имен в первичном столбце или установить его уникальным.
Ответ 13
У меня была проблема, и метод, с которым Майк советовал отчасти отчасти, имел ошибку Dublicate Column name = '0' и изменил синтаксис вашего запроса как это `
$tQ = "INSERT INTO names (name_id, surname_id, sum, sum2, sum3,sum4,sum5)
SELECT '$name', '$surname', '$sum', '$sum2', '$sum3','$sum4','$sum5'
FROM DUAL
WHERE NOT EXISTS (
SELECT sum FROM names WHERE name_id = '$name'
AND surname_id = '$surname') LIMIT 1;";
Проблема заключалась в именах столбцов. sum3 был равен sum4, а mysql выбрал имена дубликатов столбцов, и я написал код в этом синтаксисе, и он отлично работал,
Ответ 14
У меня была аналогичная проблема, и мне нужно было вставить несколько, если они не были. Поэтому из приведенных выше примеров я пришел к этой комбинации... это здесь на всякий случай, если кому-то это понадобится.
Примечание:
Мне нужно было определять имя везде, где MSSQL требовал его... MySQL работает с * тоже.
INSERT INTO names (name)
SELECT name
FROM
(
SELECT name
FROM
(
SELECT 'Test 4' as name
) AS tmp_single
WHERE NOT EXISTS
(
SELECT name FROM names WHERE name = 'Test 4'
)
UNION ALL
SELECT name
FROM
(
SELECT 'Test 5' as name
) AS tmp_single
WHERE NOT EXISTS
(
SELECT name FROM names WHERE name = 'Test 5'
)
) tmp_all;
MySQL: CREATE TABLE names
( OID
int (11) NOT NULL AUTO_INCREMENT, name
varchar (32) COLLATE utf8_unicode_ci NOT NULL, ПЕРВИЧНЫЙ КЛЮЧ (OID
), УНИКАЛЬНЫЙ КЛЮЧ name_UNIQUE
(name
) ) ENGINE = InnoDB AUTO_INCREMENT = 1;
или
MSSQL: CREATE TABLE [имена] ( [OID] INT IDENTITY (1, 1) NOT NULL, [имя] NVARCHAR (32) NOT NULL, ПЕРВИЧНАЯ КЛАВИАТУРА ([OID] ASC) ); CREATE UNIQUE NONCLUSTERED INDEX [Index_Names_Name] ON [имена] ([имя] ASC);
Ответ 15
Этот запрос может быть использован в PHP-коде.
У меня есть столбец идентификатора в этой таблице, поэтому мне нужно проверить дублирование для всех столбцов, кроме этого столбца идентификатора:
#need to change values
SET @goodsType = 1, @sybType=5, @deviceId = asdf12345SDFasdf2345;
INSERT INTO `devices` (`goodsTypeId`, `goodsId`, `deviceId`) #need to change tablename and columnsnames
SELECT * FROM (SELECT @goodsType, @sybType, @deviceId) AS tmp
WHERE NOT EXISTS (
SELECT 'goodsTypeId' FROM `devices` #need to change tablename and columns names
WHERE `goodsTypeId` = @goodsType
AND `goodsId` = @sybType
AND `deviceId` = @deviceId
) LIMIT 1;
и теперь новый элемент будет добавлен только в случае, если не существует строки со значениями, сконфигурированными в строке SET
Ответ 16
В Microsoft SQL Server я могу использовать оператор IF:
if not exists (select * from table where name = ...)
insert into table...