На первый взгляд, вопрос в заголовке поста звучит по-дурацки. Всякий, кто хоть немного знаком с SQL синтаксисом, непременно вспомнит про ALTER TABLE и ADD COLUMN, с помощью которых, работа делается легко и непринуждённо. Но SQLite, как известно, имеет некоторые ограничения, в силу своей архитектуры, и к сожалению, у неё есть свои особенности в работе с командной ALTER TABLE.
А особенности эти таковы. SQLite версии 2 вообще не знает такой команды, как ALTER TABLE. SQLite начиная с версии 3.2.0 такую команду знает, и выполняет, правда опять же - с некоторыми ограничениями. Вот что на этот счёт говорит официальный сайт "скулайта":
Эти вещи нужно иметь в виду, если вы собираетесь пользоваться ALTER TABLE в SQLite базе. Но учитывая, что для SQLite2 этот вариант вообще неприемлем, ищем альтернативное решение. По большому счёту, долго думать не приходится, т.к. оно очевидно. Делаем всю операцию через промежуточную таблицу: создаём её, копируем туда все поля из старой таблицы, удаляем старую, заново создаём её (с тем же самым именем и добавленным полем) и снова копируем в неё всю инфу. После чего удаляем промежуточную страницу, которая больше не нужна. Звучит может и страшно, но если посмотрите на код, то всё станет понятно (в примере мы добавляем одну колонку, под именем reserved):
Обратите внимание, как выглядит запрос SELECT (*,NULL). Эта конструкция берёт все значения из старой таблицы и добавляет NULL для нового поля. Если этого не сделать, SQL будет ругаться на несоответствие количества полей. Соответственно, если мы добавляем два поля, то и NULL придётся вставить дважды.
Да, аналогичным образом делается и удаление колонки из таблицы SQLite, точно так же, используя промежуточную таблицу для хранения полей. Только в этом случае после SELECT'а перечисляются лишь нужные нам поля, исключая то поле, которое мы собираемся удалить. Ну, я надеюсь, что суть понятна.
А особенности эти таковы. SQLite версии 2 вообще не знает такой команды, как ALTER TABLE. SQLite начиная с версии 3.2.0 такую команду знает, и выполняет, правда опять же - с некоторыми ограничениями. Вот что на этот счёт говорит официальный сайт "скулайта":
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table.
The ADD COLUMN syntax is used to add a new column to an existing table. The new column is always appended to the end of the list of existing columns. After ADD COLUMN has been run on a database, that database will not be readable by SQLite version 3.1.3 and earlier.
Эти вещи нужно иметь в виду, если вы собираетесь пользоваться ALTER TABLE в SQLite базе. Но учитывая, что для SQLite2 этот вариант вообще неприемлем, ищем альтернативное решение. По большому счёту, долго думать не приходится, т.к. оно очевидно. Делаем всю операцию через промежуточную таблицу: создаём её, копируем туда все поля из старой таблицы, удаляем старую, заново создаём её (с тем же самым именем и добавленным полем) и снова копируем в неё всю инфу. После чего удаляем промежуточную страницу, которая больше не нужна. Звучит может и страшно, но если посмотрите на код, то всё станет понятно (в примере мы добавляем одну колонку, под именем reserved):
CREATE TABLE temp_table (
num INTEGER PRIMARY KEY,
id TEXT,
name TEXT,
reserved TEXT
);
INSERT INTO temp_table SELECT *,NULL FROM category;
DROP TABLE category;
CREATE TABLE category (
num INTEGER PRIMARY KEY,
id TEXT,
name TEXT,
reserved TEXT
);
INSERT INTO category SELECT * FROM temp_table;
DROP TABLE temp_table;
Обратите внимание, как выглядит запрос SELECT (*,NULL). Эта конструкция берёт все значения из старой таблицы и добавляет NULL для нового поля. Если этого не сделать, SQL будет ругаться на несоответствие количества полей. Соответственно, если мы добавляем два поля, то и NULL придётся вставить дважды.
Да, аналогичным образом делается и удаление колонки из таблицы SQLite, точно так же, используя промежуточную таблицу для хранения полей. Только в этом случае после SELECT'а перечисляются лишь нужные нам поля, исключая то поле, которое мы собираемся удалить. Ну, я надеюсь, что суть понятна.