Как «вставить, если не существует» в MySQL?

ваш сервер node.js работает на порту, определенном в конце скрипта. Иногда 3000. но может быть что угодно. Правильный способ доступа других - это, как вы говорите ...

http: //your.network.ip.address: port / , например. http://192.168.0.3:3000

проверьте, что у вас есть правильный порт - и IP-адрес в сети - не интернет-ip.

В противном случае , возможно, порты блокируются вашим маршрутизатором. Попробуйте использовать 8080 или 80, чтобы обойти это - в противном случае повторно настройте маршрутизатор.

758
задан warren 27 March 2018 в 21:00
поделиться

6 ответов

используйте INSERT IGNORE INTO table

см. http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists -syntax.html

есть также синтаксис INSERT… ON DUPLICATE KEY UPDATE , пояснения можно найти на dev.mysql.com


Сообщение с bogdan.org.ua согласно Веб-кэш Google :

18 октября 2007 г.

Для начала: в последней версии MySQL синтаксис, представленный в заголовке, не соответствует возможное. Но есть несколько очень простых способов добиться того, что ожидается при использовании существующих функций.

Есть 3 возможных решения: с помощью INSERT IGNORE, REPLACE или INSERT… ON DUPLICATE KEY UPDATE.

Представьте, что у нас есть таблица:

 CREATE TABLE `transcripts` (
`ensembl_transcript_id` varchar (20) НЕ NULL,
`transcript_chrom_start` int (10) unsigned NOT NULL,
`transcript_chrom_end` int (10) без знака NOT NULL,
ПЕРВИЧНЫЙ КЛЮЧ (ʻensembl_transcript_id`)
) ДВИГАТЕЛЬ = СИМВОЛЫ ПО УМОЛЧАНИЮ InnoDB = latin1;

Теперь представьте, что у нас есть автоматический конвейер, импортирующий стенограммы. метаданные из Ensembl, и что по разным причинам конвейер может быть сломан на любом этапе исполнения. Таким образом, нам нужно обеспечить два вещи: 1) повторные запуски конвейера не уничтожат наши база данных, и 2) повторные казни не умрут из-за ошибки первичного ключа.

Метод 1: использование REPLACE

Это очень просто:

 REPLACE INTO `transcripts`
SET ʻensembl_transcript_id` = 'ENSORGT00000000001',
transcript_chrom_start = 12345,
`transcript_chrom_end` = 12678;

Если запись существует, она будет перезаписана; если это еще не существует, он будет создан. Однако использование этого метода неэффективно. для нашего случая: нам не нужно перезаписывать существующие записи, это нормально просто пропустить их.

Метод 2: использование INSERT IGNORE Также очень просто:

 INSERT IGNORE INTO `transcripts`
SET ʻensembl_transcript_id` = 'ENSORGT00000000001',
transcript_chrom_start = 12345,
`transcript_chrom_end` = 12678;

Здесь, если ensembl_transcript_id уже присутствует в база данных, она будет автоматически пропущена (проигнорирована). (Чтобы быть более точным, вот цитата из справочного руководства MySQL: «Если вы используете IGNORE ключевое слово, ошибки, возникающие при выполнении оператора INSERT, вместо этого рассматриваются как предупреждения. Например, без IGNORE строка, дублирует существующий индекс UNIQUE или значение PRIMARY KEY в таблице вызывает ошибку дублирования ключа, и оператор прерывается ».) Если запись еще не существует, она будет создана.

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

Есть еще один вариант: использовать INSERT… ON DUPLICATE KEY UPDATE синтаксис, а в части UPDATE просто ничего не делать, делать какие-то бессмысленные (пустая) операция, такая как вычисление 0 + 0 (Джеффрей предлагает выполнить id = присвоение идентификатора для механизма оптимизации MySQL, чтобы игнорировать это операция). Преимущество этого метода в том, что он игнорирует только повторяющиеся ключевые события и все еще прерывается при других ошибках.

В качестве последнего примечания: этот пост был вдохновлен Xaprb. Я бы также посоветовал проконсультируйтесь с его другим сообщением о написании гибких SQL-запросов.

756
ответ дан 22 November 2019 в 21:22
поделиться

Что-то стоящее отметить - то, которые ВСТАВЛЯЮТ, ИГНОРИРУЮТ, все еще увеличит первичный ключ, имел ли оператор успех или не точно так же, как нормальная ВСТАВКА будет.

Это вызовет разрывы в Ваших первичных ключах, которые могли бы сделать программиста мысленно нестабильным. Или если Ваше приложение плохо разработано и зависит от идеальных возрастающих первичных ключей, это могло бы стать головной болью.

Изучают innodb_autoinc_lock_mode = 0 (настройка сервера, и идет с небольшим хитом производительности), или используйте ВЫБОР сначала, чтобы удостовериться, что Ваш запрос не перестанет работать (который также идет с хитом производительности и дополнительным кодом).

1
ответ дан 22 November 2019 в 21:22
поделиться

INSERT INTO tableA (column1, column2) ВЫБИРАЮТ value1, value2 ОТ tableB, ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ 1 ИЗ tableA b где b.key=a.key)

, соответствуйте столбцам согласно своим требованиям (b.key, a.key и т.д.).

-1
ответ дан 22 November 2019 в 21:22
поделиться

при обновлении дублированного ключа или игнорирование вставки могут быть жизнеспособными решениями с MySQL.


Пример при обновлении дублированного ключа обновление на основе mysql.com

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

UPDATE table SET c=c+1 WHERE a=1;

Пример игнорирования вставки на основе mysql.com

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

Или:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    SET col_name={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

Или:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]
55
ответ дан 22 November 2019 в 21:22
поделиться

Любое простое ограничение должно работать, если допустимо исключение. Примеры:

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

Извините, это кажется обманчиво простым. Я знаю, что это выглядит плохо, если вы поделитесь с нами ссылкой. ; - (

Но я тем не менее даю этот ответ, потому что кажется, что он удовлетворяет ваши потребности. (Если нет, это может привести к обновлению ваших требований, что также было бы «Хорошей вещью» (TM)). Отредактировано : если вставка нарушит ограничение уникальности базы данных, на уровне базы данных выдается исключение, передаваемое драйвером. Это обязательно остановит ваш скрипт в случае сбоя. В PHP должна быть возможность адресовать этот случай ...

24
ответ дан 22 November 2019 в 21:22
поделиться

Решение:

INSERT INTO `table` (`value1`, `value2`) 
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL 
WHERE NOT EXISTS (SELECT * FROM `table` 
      WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1) 

Объяснение:

Внутренний запрос

SELECT * FROM `table` 
      WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1

используемый в качестве WHERE NOT EXISTS-условия, определяет, существует ли уже ряд с данными, которые нужно вставить. После обнаружения одного такого ряда запрос может быть остановлен, отсюда LIMIT 1 (микрооптимизация, может быть опущена).

Промежуточный запрос

SELECT 'stuff for value1', 'stuff for value2' FROM DUAL

представляет значения для вставки. DUAL относится к специальной таблице с одной строкой и одним столбцом, присутствующей по умолчанию во всех базах данных Oracle (см. https://en.wikipedia.org/wiki/DUAL_table). На MySQL-сервере версии 5.7.26 я получил корректный запрос при опущении FROM DUAL, но более старые версии (например, 5.5.60), похоже, требуют информацию FROM. При использовании WHERE NOT EXISTS промежуточный запрос возвращает пустой набор результатов, если внутренний запрос нашел совпадающие данные.

Внешний запрос

INSERT INTO `table` (`value1`, `value2`) 

вставляет данные, если они были возвращены промежуточным запросом.

186
ответ дан 22 November 2019 в 21:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: