#sqlite
#sqlite
Вопрос:
Я хотел бы сделать следующее в sqlite.
Для определенных прикладных задач (в основном создание) вставьте строку в таблицу и присвоите ее столбцу идентификатора новое уникальное значение.
Однако для других прикладных задач (в основном задач аннотации или обновления) он может назначить строку той же таблице с существующим значением столбца идентификатора. Это исключает использование первичного ключа автоматического создания.
Как лучше всего это сделать?
Ответ №1:
Способ может заключаться в том, чтобы имитировать генерацию столбца rowid, но не ограничивать его УНИКАЛЬНОСТЬЮ.
напр.
CREATE TABLE IF NOT EXISTS thetable (id INTEGER, other TEXT); /* add with unique id */ INSERT INTO thetable VALUES((SELECT coalesce(max(id),0) 1 FROM thetable),'blah1'); INSERT INTO thetable VALUES((SELECT coalesce(max(id),0) 1 FROM thetable),'blah2'); INSERT INTO thetable VALUES((SELECT coalesce(max(id),0) 1 FROM thetable),'blah3'); /* add with any value existing or not */ INSERT INTO thetable VALUES(2,'blahx'); INSERT INTO thetable VALUES(2,'blahy'); INSERT INTO thetable VALUES(2000,'blahz'); /* and another unique */ INSERT INTO thetable VALUES((SELECT coalesce(max(id),0) 1 FROM thetable),'blah9999'); SELECT rowid AS therealid,* FROM thetable;
Это приводит к :-
Therealid использует обычно скрытый столбец rowid, который всегда существует, если только таблица не была определена с помощью предложения WITHOUT ROWID.
Другим способом, который был бы более эффективным, но не всегда может привести к уникальному значению, может быть использование функции random() для генерации случайного значения между -9223372036854775808 и 9223372036854775807, например
CREATE TABLE IF NOT EXISTS anothertable (id INTEGER DEFAULT (random()), other TEXT); INSERT INTO anothertable (other) VALUES('blah1'),('blah2'),('blah3'); INSERT INTO anothertable VALUES(2,'blahx'); INSERT INTO anothertable VALUES(2,'blahy'); INSERT INTO anothertable VALUES(2000,'blahz'); INSERT INTO anothertable (other) VALUES('blah9999'); SELECT rowid AS therealid,* FROM anothertable;
Это приводит к (значения не согласуются) :-