Это может быть сделано с использованием синтаксиса * без необходимости знать схему таблицы (кроме имени первичного ключа). Хитрость в том, чтобы создать временную таблицу с использованием синтаксиса 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, не имеет первичного ключа и каких-либо ограничений.
Если вы хотите по-настоящему модно, вы можете добавить триггер, который обновляет третью таблицу, которая отображает старые первичные ключи на вновь созданные первичные ключи.