Подтвердить что ты не робот

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, это просто простой тестовый пример.

4b9b3361

Ответ 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.