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

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

из документации SQLite для ALTER TABLE, Я понимаю, что это невозможно сделать "легко" (т. е. один оператор ALTER TABLE).

Мне было интересно, кто-то знал об общем способе SQL такие вещи с SQLite.

13 ответов


это было просто исправить с 2018-09-15 (3.25.0)

инструменты :

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

вы можете найти новый синтаксис, оформленными в соответствии ALTER TABLE

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

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


скажем, у вас есть таблица и нужно переименовать "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, если вы хотите только переименовать столбец, удалить ограничение 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  

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


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

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

ALTER TABLE SYNTAX


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

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

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


недавно мне пришлось сделать это в SQLite3 с таблицей с именем точки С colunms id, lon, lat. Erroneusly, когда таблица была импортирована, значения широты, где хранятся в долгота столбец и viceversa, поэтому очевидным решением было бы переименовать эти столбцы. Так вот фишка была:

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. Команда Alter таблицы в SQLite позволяет пользователю переименовывать таблица или добавление нового столбца в существующая таблица. невозможно переименовать colum, удалить столбец или добавить или удалить ограничения из таблицы.

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


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

GUI, на который я приземлился, чтобы делать операции SQLite, - это базовый. В нем есть отличное окно журнала, которое показывает все команды, которые были выполнены. Выполнение переименования столбца через Base заполняет окно журнала необходимым команды:

Base log window

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

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


изменить столбец таблицы на

 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, который делает это. Lyckily, этот инструмент ведет журнал всех операций, выполняемых пользователем или приложением. Сделав это один раз и посмотрев на журнал приложений, вы увидите соответствующий код. Скопируйте запрос и вставьте его по мере необходимости. Работать на меня. Надеюсь, это поможет


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

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

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

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

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


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

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

  1. начать a торговая операция.

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

  3. активировать редактирование схемы с помощью PRAGMA writable_schema=ON.

  4. запустите инструкцию UPDATE, чтобы изменить определение таблицы X в таблице sqlite_master: UPDATE SQLITE_MASTER SET sql=... Где type= 'table' и name= 'X';

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

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

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

  6. увеличьте номер версии схемы с помощью PRAGMA schema_version=X, где X на один больше, чем старый номер версии схемы, найденный на Шаге 2 выше.

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

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

  9. зафиксировать начатую транзакцию Шаг 1 выше.


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

ex:

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


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