sqlite-как заставить INSERT или 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 trigger, это просто простой тестовый случай.

2 ответов


заменить

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|

Это будет работать только для поля первичного ключа или уникального ограничения:

необязательное предложение conflict - позволяет спецификацию альтернативный алгоритм разрешения конфликтов ограничений для использования во время вот этот!--4-->вставить