SQLITE: как я могу превратить столбец rowid в обычный столбец - PullRequest
0 голосов
/ 14 октября 2018

Скажем, я создаю таблицу и вставляю строку, выполнив:

CREATE TABLE people (first_name text NOT NULL, last_name text NOT NULL );
INSERT INTO people (first_name, last_name) VALUES ('John', 'Doe');

Я могу выполнить:

SELECT rowid as ID, first_name, last_name FROM people

и получить три столбца данных, как и ожидалось.

Однако, скажем, я хотел превратить автоматический столбец rowid в обычный столбец, чтобы идентификаторы строк не менялись при их удалении и т. Д.

Как я могу это сделать?

Я пытался:

ALTER TABLE people ADD people_id INTEGER;
ALTER TABLE people ADD PRIMARY KEY (people_id);

Первый оператор завершается успешно, но второй дает мне ошибку:

near "PRIMARY": syntax error: ALTER TABLE people ADD PRIMARY

Если я создал таблицуизначально как:

CREATE TABLE people (people_id INTEGER PRIMARY KEY, first_name text NOT NULL, last_name text NOT NULL );

Я бы с самого начала выбрал тип таблицы, которую я ищу.

Важно, чтобы значение rowid поддерживалось в столбце people_id.Например, предположим, что у Джона Доу было 47 человек.После преобразования people_id для John Doe должен быть равен 47.

Полагаю, я могу просто скопировать данные из одной таблицы в другую, но мне интересно, есть ли лучший или стандартный способ сделать этовид трансформации.

Ответы [ 3 ]

0 голосов
/ 14 октября 2018

Ответ Шона звучит здраво (и я проголосовал за него), но я предложу вариант того, что, как мне кажется, немного точнее, поскольку новая таблица не заканчивается в схеме с кавычками:

TRANSACTION;
ALTER TABLE people RENAME TO old_people;
CREATE TABLE people(people_id INTEGER PRIMARY KEY
                  , first_name TEXT NOT NULL,
                  , last_name TEXT NOT NULL);
INSERT INTO people(people_id, first_name, last_name)
            SELECT rowid, first_name, last_name FROM old_people;
DROP TABLE old_people;
COMMIT;
VACUUM;
0 голосов
/ 14 октября 2018

Пока фактический формат хранения таблицы не изменяется, вы можете использовать чрезвычайно опасный backdoor , чтобы изменить определение таблицы:

PRAGMA writable_schema = on;

UPDATE sqlite_master
SET sql = 'CREATE TABLE people(people_id INTEGER PRIMARY KEY, first_name text NOT NULL, last_name text NOT NULL )'
WHERE type = 'table'
  AND name = 'people';

-- and now re-open the database file
0 голосов
/ 14 октября 2018

Вам нужно создать новую таблицу, скопировать все заново, удалить старую таблицу и переименовать новую:

CREATE TABLE new_people(people_id INTEGER PRIMARY KEY
                      , first_name TEXT NOT NULL,
                      , last_name TEXT NOT NULL);
INSERT INTO new_people(first_name, last_name) SELECT first_name, last_name FROM people;
DROP TABLE people;
ALTER TABLE new_people RENAME TO people;
...