Как переименовать столбец в таблице базы данных SQLite?

StackOverflow https://stackoverflow.com/questions/805363

  •  03-07-2019
  •  | 
  •  

Вопрос

Мне нужно было бы переименовать несколько столбцов в некоторых таблицах базы данных SQLite.Я знаю, что аналогичный вопрос ранее уже задавался вопрос о stackoverflow, но это было для SQL в целом, а случай SQLite не упоминался.

Из документации SQLite для ИЗМЕНИТЬ ТАБЛИЦУ, Я так понимаю, что сделать это «легко» (т.е.один оператор ALTER TABLE).

Мне было интересно, кто-нибудь знает общий способ SQL, позволяющий сделать это с помощью SQLite.

Это было полезно?

Решение

Это было только что исправлено с помощью 2018-09-15 (3.25.0)

Улучшает ALTER TABLE команда:

  • Добавьте поддержку переименования столбцов в таблице с помощью ALTER TABLE стол RENAME COLUMN oldname TO newname.
  • Исправьте функцию переименования таблицы, чтобы она также обновляла ссылки на переименованную таблицу в триггерах и представлениях.

Вы можете найти новый синтаксис, описанный в разделе ALTER TABLE

А RENAME COLUMN TO синтаксис изменяет имя-столбца таблицы имя-столбца на новое-имя-столбца.Имя столбца изменяется как в самом определении таблицы, так и во всех индексах, триггерах и представлениях, ссылающихся на столбец.Если изменение имени столбца приведет к семантической неоднозначности в триггере или представлении, то RENAME COLUMN завершается с ошибкой, и никакие изменения не применяются.

enter image description here Источник изображения: https://www.sqlite.org/images/syntax/alter-table-stmt.gif

Пример:

CREATE TABLE tab AS VALUES(1);

SELECT * FROM tab;

ALTER TABLE tab RENAME TO tab_new;

SELECT * FROM tab_new;

демо-версия db-fiddle.com


Поддержка Android

На момент написания, API Android 27 использует пакет SQLite версии 3.19..

Учитывая текущую версию, которую использует Android, и то, что это обновление входит в версию SQLite 3.25.0, я бы сказал, что вам придется немного подождать (приблизительно API 33), прежде чем поддержка этого будет добавлена ​​в Android.

И даже в этом случае, если вам потребуется поддержка каких-либо версий старше API 33, вы не сможете это использовать.

Другие советы

Допустим, у вас есть таблица и вам нужно переименовать «colb» в «col_b»:

Сначала вы переименовываете старую таблицу:

ALTER TABLE orig_table_name RENAME TO tmp_table_name;

Затем создайте новую таблицу на основе старой таблицы, но с обновленным именем столбца:

CREATE TABLE orig_table_name (
  col_a INT
, col_b INT
);

Затем скопируйте содержимое исходной таблицы.

INSERT INTO orig_table_name(col_a, col_b)
SELECT col_a, colb
FROM tmp_table_name;

Наконец, удалите старую таблицу.

DROP TABLE tmp_table_name;

Обернув все это в BEGIN TRANSACTION; и COMMIT; это тоже, наверное, хорошая идея.

Хотя это правда, что ALTER COLUMN не существует, но если вы хотите только переименовать столбец, удалить ограничение NOT NULL или изменить тип данных, вы можете использовать следующий набор команд:

Примечание:Эти команды могут повредить вашу базу данных, поэтому убедитесь, что у вас есть резервная копия.

PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
PRAGMA writable_schema = 0;

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

Например:

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT NULL);  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
Error: BOOKS.publication_date may not be NULL  
sqlite> PRAGMA writable_schema = 1; 
sqlite> UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';  
sqlite> PRAGMA writable_schema = 0;  
sqlite> .q  

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
sqlite> .q  

ССЫЛКИ СЛЕДУЮЩИЕ:


прагма writable_schema
Когда эта прагма включена, таблицы SQLITE_MASTER, в которых находится база данных, можно изменить с помощью обычных операторов UPDATE, INSERT и DELETE.Предупреждение:неправильное использование этой прагмы может легко привести к повреждению файла базы данных.

изменить таблицу
SQLite поддерживает ограниченное подмножество ALTER TABLE.Команда ALTER TABLE в SQLite позволяет пользователю переименовать таблицу или добавить новый столбец в существующую таблицу.Невозможно переименовать столбец, удалить столбец, а также добавить или удалить ограничения из таблицы.

ALTER TABLE SYNTAX

Покопавшись, я нашел этот мультиплатформенный (Linux | Mac | Windows) графический инструмент под названием Браузер БД для SQLite это на самом деле позволяет переименовывать столбцы очень удобным для пользователя способом!

Редактировать | Изменить таблицу | Выберите таблицу | Редактировать поле.Клик-клик!Вуаля!

Однако, если кто-то захочет поделиться программным способом сделать это, я буду рад узнать!

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

create table points_tmp as select id, lon as lat, lat as lon from points;
drop table points;
alter table points_tmp rename to points;

Я надеюсь, что это будет полезно для вас!

Цитируя SQLite-документация:

SQLite поддерживает ограниченную подмножество таблицы альтер.Команда Alter Table в SQLite позволяет пользователю переименовать таблицу или добавить новый столбец в существующую таблицу. Невозможно переименовать столбец, удалить столбец, а также добавить или удалить ограничения из таблицы.

Конечно, вы можете создать новую таблицу с новым макетом, SELECT * FROM old_table, и заполните новую таблицу полученными значениями.

Во-первых, это одна из тех вещей, которые вызывают у меня пощечину от удивления:переименование столбца требует создания совершенно новой таблицы и копирования данных из старой таблицы в новую таблицу...

Графический интерфейс, который я использовал для выполнения операций SQLite, База.У него есть отличное окно журнала, в котором показаны все выполненные команды.При переименовании столбца через Base окно журнала заполняется необходимыми командами:

Base log window

Затем их можно легко скопировать и вставить туда, где они могут вам понадобиться.Для меня это АктивныйAndroid файл миграции.Приятным моментом также является то, что скопированные данные включают только команды SQLite, а не временные метки и т. д.

Надеюсь, это сэкономит некоторым людям время.

изменить столбец таблицы <id> на <_id>

 String LastId = "id";

    database.execSQL("ALTER TABLE " + PhraseContract.TABLE_NAME + " RENAME TO " + PhraseContract.TABLE_NAME + "old");
    database.execSQL("CREATE TABLE " + PhraseContract.TABLE_NAME
    +"("
            + PhraseContract.COLUMN_ID + " INTEGER PRIMARY KEY,"
            + PhraseContract.COLUMN_PHRASE + " text ,"
            + PhraseContract.COLUMN_ORDER  + " text ,"
            + PhraseContract.COLUMN_FROM_A_LANG + " text"
    +")"
    );
    database.execSQL("INSERT INTO " +
            PhraseContract.TABLE_NAME + "("+ PhraseContract.COLUMN_ID +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +")" +
            " SELECT " + LastId +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +
            " FROM " + PhraseContract.TABLE_NAME + "old");
    database.execSQL("DROP TABLE " + PhraseContract.TABLE_NAME + "old");

Как упоминалось ранее, существует инструмент SQLite Database Browser, который делает это.К счастью, этот инструмент ведет журнал всех операций, выполняемых пользователем или приложением.Сделав это один раз и просмотрев журнал приложения, вы увидите задействованный код.Скопируйте запрос и вставьте его по мере необходимости.Работал для меня.Надеюсь это поможет

Создайте новый столбец с нужным именем столбца:COLНовый.

ALTER TABLE {tableName} ADD COLUMN COLNew {type};

Скопируйте содержимое старого столбца COLold в новый столбец COLNew.

INSERT INTO {tableName} (COLNew) SELECT {COLOld} FROM {tableName}

Примечание:скобки необходимы в строке выше.

Из официальной документации

Более простая и быстрая процедура опционально может использоваться для некоторых изменений, которые никак не влияют на содержимое диска.Следующая более простая процедура подходит для удаления ограничений CHECK или FOREIGN KEY или NOT NULL: переименование столбцов, или добавление, удаление или изменение значений по умолчанию в столбце.

  1. Начать транзакцию.

  2. Запустите PRAGMA Schema_version, чтобы определить текущий номер версии схемы.Этот номер понадобится для шага 6 ниже.

  3. Активируйте редактирование схемы, используя PRAGMA writable_schema=ON.

  4. Запустите инструкцию UPDATE, чтобы изменить определение таблицы X в таблице sqlite_master:ОБНОВЛЕНИЕ sqlite_master SET sql=...ГДЕ type='table' AND name='X';

    Осторожность:Внесение такого изменения в таблицу sqlite_master приведет к повреждению базы данных и ее нечитаемости, если изменение содержит синтаксическую ошибку.Предлагается провести тщательное тестирование оператора UPDATE на отдельной пустой базе данных, прежде чем использовать его в базе данных, содержащей важные данные.

  5. Если изменение таблицы X также влияет на другие таблицы или индексы или триггеры являются представлениями внутри схемы, запустите инструкции UPDATE, чтобы также изменить индексы и представления этих других таблиц.Например, если имя столбца изменится, все ограничения FOREIGN KEY, триггеры, индексы и представления, ссылающиеся на этот столбец, должны быть изменены.

    Осторожность:Опять же, подобные изменения в таблице sqlite_master сделают базу данных поврежденной и нечитаемой, если изменение содержит ошибку.Тщательно протестируйте всю эту процедуру на отдельной тестовой базе данных, прежде чем использовать ее в базе данных, содержащей важные данные, и/или сделайте резервные копии важных баз данных перед запуском этой процедуры.

  6. Увеличьте номер версии схемы, используя PRAGMAschema_version=X, где X на единицу больше, чем старый номер версии схемы, найденный на шаге 2 выше.

  7. Отключите редактирование схемы, используя PRAGMA writable_schema=OFF.

  8. (Необязательно) Запустите проверку целостности PRAGMA, чтобы убедиться, что изменения схемы не повредили базу данных.

  9. Зафиксируйте транзакцию, начатую на шаге 1 выше.

Один из вариантов, если вам нужно сделать это в крайнем случае, и если ваш исходный столбец был создан со значением по умолчанию, — создать новый столбец, который вы хотите, скопировать в него содержимое и, по сути, «отказаться» от старого столбца (он остается присутствует, но вы его просто не используете/обновляете и т. д.)

бывший:

alter table TABLE_NAME ADD COLUMN new_column_name TYPE NOT NULL DEFAULT '';
update TABLE_NAME set new_column_name = old_column_name;
update TABLE_NAME set old_column_name = ''; -- abandon old column, basically

При этом остается столбец (и если он был создан с NOT NULL, но без значения по умолчанию, то будущие вставки, игнорирующие его, могут завершиться неудачно), но если это просто одноразовая таблица, компромиссы могут быть приемлемыми.В противном случае используйте один из других ответов, упомянутых здесь, или другую базу данных, которая позволяет переименовывать столбцы.

ДЕЛО 1 :SQLite 3.25.0+

Только версия 3.25.0 SQLite поддерживает переименование столбцов.Если ваше устройство соответствует этому требованию, все довольно просто.Следующий запрос решит вашу проблему:

ALTER TABLE "MyTable" RENAME COLUMN "OldColumn" TO "NewColumn";

СЛУЧАЙ 2:Старые версии SQLite

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

Например, если у вас есть такая таблица:

CREATE TABLE student(Name TEXT, Department TEXT, Location TEXT)

И если вы хотите изменить имя столбца Location

Шаг 1: Переименуйте исходную таблицу:

ALTER TABLE student RENAME TO student_temp;

Шаг 2: Теперь создайте новую таблицу student с правильным именем столбца:

CREATE TABLE student(Name TEXT, Department TEXT, Address TEXT)

Шаг 3: Скопируйте данные из исходной таблицы в новую таблицу:

INSERT INTO student(Name, Department, Address) SELECT Name, Department, Location FROM student_temp;

Примечание:Приведенная выше команда должна состоять из одной строки.

Шаг 4: Удалите исходную таблицу:

DROP TABLE student_temp;

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

С момента версии 2018-09-15 (3.25.0) SQLite поддерживает переименование столбцов

https://sqlite.org/changes.html

sqlite3 yourdb .dump > /tmp/db.txt
отредактируйте /tmp/db.txt измените имя столбца в строке создания
sqlite2 yourdb2 </tmp/db.txt
mv/переместить yourdb2 yourdb

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top