Jak zmienić nazwę kolumny w tabeli bazy danych SQLite?

Musiałbym zmienić nazwę kilku kolumn w niektórych tabelach w bazie danych SQLite. Wiem, że podobne pytanie zostało wcześniej zadane na stackoverflow, ale ogólnie było to dla SQL, a przypadek SQLite nie został wymieniony.

Z dokumentacji SQLite dla ALTER TABLE wnioskuję, że nie jest możliwe wykonanie czegoś takiego "łatwo" (np. pojedyncza instrukcja ALTER TABLE).

Zastanawiałem się, czy ktoś zna ogólny SQL sposób na zrobienie czegoś takiego z SQLite.

Author: Community, 2009-04-30

13 answers

To zostało naprawione z 2018-09-15 (3.25.0)

Rozszerzenie polecenia ALTER TABLE:

  • Dodaj obsługę zmiany nazw kolumn w tabeli za pomocą ALTER TABLE table RENAME COLUMN oldname TO newname.
  • Fix table rename feature tak, że aktualizuje również odniesienia do zmienionej tabeli w wyzwalaczach i widokach.

Nową składnię można znaleźć pod ALTER TABLE

Składnia RENAME COLUMN TO zmienia nazwę kolumny tabeli table-name do new-column-name. Nazwa kolumny jest zmieniana zarówno w samej definicji tabeli, jak i we wszystkich indeksach, wyzwalaczach i widokach odwołujących się do kolumny. Jeśli zmiana nazwy kolumny spowodowałaby niejednoznaczność semantyczną w wyzwalaczu lub widoku, to RENAME COLUMN zakończy się błędem i nie zostaną zastosowane żadne zmiany.

Tutaj wpisz opis obrazka źródło obrazu: https://www.sqlite.org/images/syntax/alter-table-stmt.gif

 3
Author: Lukasz Szozda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-16 10:59:47

Powiedz, że masz tabelę i musisz zmienić nazwę "colb " na"col_b":

Najpierw zmieniasz nazwę starej tabeli:

ALTER TABLE orig_table_name RENAME TO tmp_table_name;

Następnie utwórz nową tabelę, opartą na starej tabeli, ale ze zaktualizowaną nazwą kolumny:

CREATE TABLE orig_table_name (
  col_a INT
, col_b INT
);

Następnie skopiuj zawartość z oryginalnej tabeli.

INSERT INTO orig_table_name(col_a, col_b)
SELECT col_a, colb
FROM tmp_table_name;
Na koniec rzuć stary stół.
DROP TABLE tmp_table_name;

Owijanie tego wszystkiego w BEGIN TRANSACTION; i COMMIT; jest również prawdopodobnie dobrym pomysłem.

 423
Author: Evan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-15 23:24:22

Chociaż prawdą jest, że nie ma zmiany kolumny, jeśli chcesz zmienić jej nazwę, porzucić ograniczenie NOT NULL lub zmienić typ danych, możesz użyć następującego zestawu poleceń:

Uwaga: te polecenia mogą uszkodzić bazę danych, więc upewnij się, że masz kopię zapasową

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;

Będziesz musiał zamknąć i ponownie otworzyć połączenie lub odkurzyć bazę danych, aby ponownie załadować zmiany do schematu.

Dla przykład:

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  

REFERENCJE:


pragma writable_schema
Gdy ta pragma jest włączona, tabele sqlite_master, w których baza danych może być zmieniana za pomocą zwykłych instrukcji UPDATE, INSERT i DELETE. Ostrzeżenie: niewłaściwe użycie tego pragma może łatwo spowodować uszkodzony plik bazy danych.

Alter table
SQLite obsługuje Ograniczony podzbiór tabeli ALTER. Polecenie ALTER TABLE w SQLite pozwala użytkownikowi zmienić nazwę tabeli lub dodać nową kolumny do istniejącej tabeli. Nie można zmienić nazwy kolumny, usunąć kolumny ani dodać lub usunąć ograniczeń z tabeli.

ZMIEŃ SKŁADNIĘ TABELI

 53
Author: Noah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 20:11:58

Grzebanie wokół, znalazłem to wieloplatformowe (Linux | Mac | Windows) graficzne narzędzie o nazwie DB Browser for SQLite , które pozwala na zmianę nazw kolumn w bardzo przyjazny dla użytkownika sposób!

Edytuj / Modyfikuj Tabelę / Wybierz Tabelę / Edytuj Pole. Click click! Voila!

Jeśli jednak ktoś chce podzielić się programowym sposobem na zrobienie tego, chętnie się dowiem!

 51
Author: joce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-25 18:19:17

Ostatnio musiałem to zrobić w SQLite3 z tabelą o nazwie points z colunms id, lon, lat. Błędnie, gdy tabela została importowana, wartości szerokości geograficznej, gdzie przechowywane w Lon kolumna i viceversa, więc oczywistą poprawką byłoby zmienić nazwy tych kolumn. Więc sztuczka była:

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;

Mam nadzieję, że to będzie dla Ciebie przydatne!

 17
Author: aizquier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-17 02:13:01

Cytowanie dokumentacji sqlite:

SQLite obsługuje Ograniczony podzbiór ALTER TABLE. Polecenie ALTER TABLE w SQLite pozwala użytkownikowi zmienić nazwę tabeli lub aby dodać nową kolumnę do istniejąca tabela. nie można zmienić nazwy kolumny, usunąć kolumny ani dodać lub usunąć ograniczeń z tabeli.

Możesz oczywiście utworzyć nową tabelę z nowym układem SELECT * FROM old_table i wypełnić nową tabelę wartościami, które będziesz odbiór.

 10
Author: Elazar Leibovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-30 04:54:39

Po pierwsze, jest to jedna z tych rzeczy, która uderza mnie w twarz z zaskoczenia: zmiana nazwy kolumny wymaga utworzenia całkowicie nowej tabeli i skopiowania danych ze starej tabeli do nowej tabeli...

GUI, na którym wylądowałem, aby wykonać operacje SQLite to Base . Ma sprytne okno dziennika, które pokazuje wszystkie polecenia, które zostały wykonane. Zmiana nazwy kolumny za pomocą bazy zapełnia okno dziennika niezbędnym polecenia:

Okno dziennika bazowego

Można je następnie łatwo skopiować i wkleić tam, gdzie mogą być potrzebne. Dla mnie jest to plik migracji ActiveAndroid . Miłym akcentem jest również to, że skopiowane dane zawierają tylko polecenia SQLite, a nie znaczniki czasu itp.

Miejmy nadzieję, że to oszczędza trochę czasu.

 7
Author: Joshua Pinter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-02 21:31:32

Zmień kolumnę tabeli na

 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");
 3
Author: Vahe Gharibyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 18:49:30

Jak wspomniano wcześniej, istnieje narzędzie SQLite Database Browser, które to robi. Narzędzie to prowadzi rejestr wszystkich operacji wykonywanych przez użytkownika lub aplikację. Robiąc to raz i patrząc na dziennik aplikacji, zobaczysz kod. Skopiuj zapytanie i wklej zgodnie z wymaganiami. Dla mnie zadziałało. Mam nadzieję, że to pomoże

 2
Author: Chris Lytridis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-06 21:20:53

Utwórz nową kolumnę o żądanej nazwie kolumny: COLNew.

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

Skopiuj zawartość starej kolumny COLOld do nowej kolumny COLNew.

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

Uwaga: nawiasy są niezbędne w powyższym wierszu.

 2
Author: Anthony Ebert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-02 07:16:29

Z oficjalnej dokumentacji

Prostsza i szybsza procedura może być opcjonalnie stosowana w przypadku niektórych zmian, które w żaden sposób nie wpływają na zawartość dysku. Poniższa prostsza procedura jest odpowiednia do usunięcia CHECK lub klucza obcego lub nie ograniczeń NULL, zmiany nazw kolumn lub dodania lub usunięcia lub zmiany wartości domyślnych w kolumnie.

  1. Rozpocznij transakcję.

  2. Uruchom PRAGMA schema_version aby określić aktualny numer wersji schematu. Ten numer będzie potrzebny do kroku 6 poniżej.

  3. Aktywuj edycję schematu używając PRAGMA writable_schema = ON.

  4. Uruchom instrukcję UPDATE, aby zmienić definicję tabeli X w tabeli sqlite_master: UPDATE SQLITE_MASTER SET sql=... WHERE type = "table" AND name= "X";

    Uwaga: taka zmiana tabeli sqlite_master spowoduje, że baza danych będzie uszkodzona i nieczytelna, jeśli zmiana zawiera błąd składni. On sugerowano, aby staranne przetestowanie instrukcji UPDATE przeprowadzić na oddzielnej pustej bazie danych przed użyciem jej w bazie danych zawierającej ważne dane.

  5. Jeśli zmiana tabeli X wpływa również na inne tabele lub indeksy lub wyzwalacze są widokami w schemacie, uruchom polecenie UPDATE, aby zmodyfikować również te indeksy i widoki innych tabel. Na przykład, jeśli zmieni się nazwa kolumny, wszystkie ograniczenia kluczy obcych, wyzwalacze, indeksy i widoki odnoszące się do tej kolumny muszą być zmodyfikowany.

    Uwaga: po raz kolejny, wprowadzenie takich zmian w tabeli sqlite_master spowoduje, że baza danych będzie uszkodzona i nieczytelna, jeśli zmiana zawiera błąd. Dokładnie przetestuj całą procedurę na oddzielnej testowej bazie danych przed użyciem jej w bazie danych zawierającej ważne dane i / lub wykonaj kopie zapasowe ważnych baz danych przed uruchomieniem tej procedury.

  6. Zwiększ numer wersji schematu używając PRAGMA schema_version=X, gdzie X jest o jeden więcej niż stary numer wersji schematu znajduje się w Kroku 2 powyżej.

  7. Wyłączanie edycji schematu za pomocą PRAGMA writable_schema = OFF.

  8. (opcjonalne) Uruchom PRAGMA integrity_check, aby sprawdzić, czy zmiany schematu nie uszkodziły bazy danych.

  9. Zatwierdź transakcję rozpoczętą w kroku 1 powyżej.

 2
Author: Mohammad Yahia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-14 16:26:10

Jedną z opcji, jeśli trzeba to zrobić w szczypcie, a jeśli początkowa kolumna została utworzona z domyślną, jest utworzenie nowej kolumny, którą chcesz, Skopiuj zawartość do niej i zasadniczo "porzuć" starą kolumnę (pozostaje obecna, ale po prostu nie używasz/nie aktualizujesz jej, itp.)

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

To pozostawia za kolumną (i jeśli została utworzona z NOT NULL, ale bez domyślnej, to przyszłe wstawki, które ją ignorują, mogą się nie udać), ale jeśli jest to tylko tabela odrzucająca, tradeoffs może być akceptowalnym. W przeciwnym razie użyj jednej z innych odpowiedzi wymienionych tutaj, lub innej bazy danych, która pozwala na zmianę nazwy kolumn.

 1
Author: rogerdpack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-20 23:03:08

Sqlite3 yourdb .dump > / tmp / db.txt
edytuj /tmp / db.txt Zmień nazwę kolumny w Utwórz linię
sqlite2 yourdb2 MV / move yourdb2 yourdb

 -3
Author: H Bosch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-04 17:34:43