Sqlite - Как заставить INSERT OR IGNORE работать
Я пытаюсь вставить данные в таблицу. Я хотел бы вставить строку, если в столбце уже нет данных - независимо от других столбцов.
CREATE TABLE t (
id INTEGER PRIMARY KEY,
name VARCHAR,
other INT
);
INSERT OR IGNORE INTO t (name) VALUES ('a');
INSERT OR IGNORE INTO t (name) VALUES ('a');
INSERT OR IGNORE INTO t (name) VALUES ('a');
С приведенным выше фрагментом я получаю 3 строки, а не 1, как я и думал. Если это имеет значение, фактический sql происходит внутри триггера INSTEAD OF INSERT
, это просто простой тестовый пример.
Ответы
Ответ 1
Заменить
CREATE TABLE t (
id INTEGER PRIMARY KEY,
name VARCHAR,
other INT
);
с
CREATE TABLE t (
id INTEGER PRIMARY KEY,
name VARCHAR UNIQUE,
other INT
);
Затем вы получите
sqlite> CREATE TABLE t (
...> id INTEGER PRIMARY KEY,
...> name VARCHAR UNIQUE,
...> other INT
...> );
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> select * from t ;
1|a|
Ответ 2
Это будет работать только для поля первичного ключа или уникальных ограничений:
Дополнительное условие конфликта разрешает спецификацию альтернативный алгоритм разрешения конфликтов ограничений для использования во время эта команда INSERT.
Далее:
Предложение ON CONFLICT применяется к ограничениям UNIQUE и NOT NULL (и ограничениям PRIMARY KEY, которые для целей настоящего раздела это то же самое, что и УНИКАЛЬНЫЕ ограничения). Алгоритм ON CONFLICT не относится к ограничениям FOREIGN KEY. Есть пять конфликтов выбор алгоритма разрешения: ROLLBACK, ABORT, FAIL, IGNORE и ЗАМЕНА. Алгоритм разрешения конфликтов по умолчанию - ABORT.