Как я могу вставить, где не существует?

Я хотел бы объединить запрос вставки с "где не существует", чтобы не нарушать ограничения PK. Однако синтаксис, такой как следующий, дает мне ошибку Incorrect syntax near the keyword 'WHERE' -

INSERT INTO myTable(columns...)
VALUES(values...)
WHERE NOT EXISTS
   (SELECT *
    FROM myTable
    WHERE pk_part1 = value1,
        AND pk_part2 = value2)

Как я могу это сделать?

(В общем, вы можете комбинировать вставку с предложением where?)

Ответы

Ответ 1

INSERT INTO myTable(columns...)
Select values...
WHERE NOT EXISTS
   (SELECT *
    FROM myTable
    WHERE pk_part1 = value1,
        AND pk_part2 = value2)

Edit: После прочтения ссылки martins, если допустимо, что лучшим решением является:

BEGIN TRY
    INSERT INTO myTable(columns...)
    values( values...)
END TRY
BEGIN CATCH
    IF ERROR_NUMBER() <> 2627
      RAISERROR etc
END CATCH;

Ответ 2

Самый простой способ сохранить уникальный список значений - либо a) установить столбец (столбцы) в качестве первичного ключа, либо b) создать уникальное ограничение для столбца (ов). Любой из них приведет к ошибке при попытке вставить/обновить значения до того, что уже существует в таблице, когда NOT EXISTS/etc не будет работать тихо - ошибка не будет выполнена, запрос будет выполнен правильно.

Тем не менее, используйте INSERT/SELECT (не включайте часть VALUES):

INSERT INTO myTable(columns...)
SELECT [statically defined values...]
  FROM ANY_TABLE
 WHERE NOT EXISTS (SELECT NULL
                     FROM myTable
                    WHERE pk_part1 = value1
                      AND pk_part2 = value2)

Ответ 3

mysql имеет запрос на игнорирование вставки:

Если вы используете ключевое слово IGNORE, ошибки, возникающие при выполнении инструкции INSERT, рассматриваются как предупреждения. Например, без IGNORE строка, которая дублирует существующий индекс UNIQUE или PRIMARY KEY в таблице, вызывает ошибку с дубликат-ключом, и оператор прерывается. С IGNORE строка все еще не вставлена, но ошибка не выдана. Преобразования данных, которые будут приводить к ошибкам, прерывают утверждение, если IGNORE не указан. С IGNORE недопустимые значения корректируются до ближайших значений и вставляются; появляются предупреждения, но утверждение не прерывается. Вы можете определить с помощью функции API mysql_info() C, сколько строк было фактически вставлено в таблицу.

http://dev.mysql.com/doc/refman/5.0/en/insert.html

ON DUPLICATE KEY UPDATE также доступно