Как вставить дубликаты строк в SQLite с уникальным идентификатором? - PullRequest
12 голосов
/ 11 ноября 2009

Это кажется достаточно простым: я хочу дублировать строку в таблице SQLite:

INSERT INTO table SELECT * FROM table WHERE rowId=5;

Если бы не было явных объявлений уникальных столбцов, оператор работал бы, но первый столбец таблицы объявлялся rowID INTEGER NOT NULL PRIMARY KEY. Есть ли способ создать простое утверждение, подобное приведенному выше, которое работает без знания схемы таблицы (кроме первого столбца)?

Ответы [ 4 ]

23 голосов
/ 23 февраля 2012

Это может быть сделано с использованием синтаксиса * без необходимости знать схему таблицы (кроме имени первичного ключа). Хитрость в том, чтобы создать временную таблицу с использованием синтаксиса CREATE TABLE AS.

В этом примере я предполагаю, что существует существующая заполненная таблица с именем "src" с INTEGER PRIMARY KEY с именем "id", а также несколько других столбцов. Чтобы дублировать строки «src», используйте следующий SQL в SQLite3:

CREATE TEMPORARY TABLE tmp AS SELECT * FROM src;
UPDATE tmp SET id = NULL;
INSERT INTO src SELECT * FROM tmp;
DROP TABLE tmp;

В приведенном выше примере дублируются все строки таблицы "src". Чтобы дублировать только нужную строку, просто добавьте предложение WHERE в первую строку. Этот пример работает, потому что таблица «tmp» не имеет ограничения первичного ключа, но «src» делает. Вставка первичных ключей NULL в src приводит к тому, что им присваиваются автоматически сгенерированные значения.

Из документации sqlite: http://www.sqlite.org/lang_createtable.html

Оператор "CREATE TABLE ... AS SELECT" создает и заполняет таблицу базы данных на основе результатов оператора SELECT. Таблица, созданная с помощью CREATE TABLE AS, не имеет первичного ключа и каких-либо ограничений.

Если вы хотите по-настоящему модно, вы можете добавить триггер, который обновляет третью таблицу, которая отображает старые первичные ключи на вновь созданные первичные ключи.

8 голосов
/ 11 ноября 2009

Нет. Вам необходимо знать схему таблицы, чтобы правильно написать оператор вставки.

Вы должны быть в состоянии написать заявление в виде:

insert into Table (column1, column2, column3) 
select column1, column2, column3
from OtherTable
where rowId = 5
5 голосов
/ 11 ноября 2009

Ну, поскольку я не смог сделать это так, как хотел, я прибег к использованию неявного идентификатора строки, который достаточно легко имеет то же имя, что и столбец rowId, который я определил явно, так что теперь я могу использовать запрос, который у меня был в вопросе, и он вставит все данные с новым rowId. Чтобы остальная часть программы работала, я просто изменил SELECT * FROM table на SELECT rowId,* FROM table и все в порядке.

0 голосов
/ 11 ноября 2009

Абсолютно нет способа сделать это. Объявление первичного ключа подразумевает, что это поле уникально. Вы не можете иметь не уникальный ПК. Невозможно создать строку с существующим PK в той же таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...