Odpowiedzi:
Masz dwie opcje. Po pierwsze, możesz po prostu dodać nową kolumnę z następującymi elementami:
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
Po drugie, i bardziej skomplikowane, ale tak naprawdę umieściłby kolumnę tam, gdzie chcesz, byłaby zmiana nazwy tabeli:
ALTER TABLE {tableName} RENAME TO TempOldTable;
Następnie utwórz nową tabelę z brakującą kolumną:
CREATE TABLE {tableName} (name TEXT, COLNew {type} DEFAULT {defaultValue}, qty INTEGER, rate REAL);
I wypełnij go starymi danymi:
INSERT INTO {tableName} (name, qty, rate) SELECT name, qty, rate FROM TempOldTable;
Następnie usuń starą tabelę:
DROP TABLE TempOldTable;
Wolałbym drugą opcję, ponieważ w razie potrzeby całkowicie zmienisz nazwę wszystkiego.
PRAGMA foreign_keys = ON;
(patrz sqlite.org/foreignkeys.html#fk_enable )
Nie dodajesz kolumn między innymi kolumnami w SQL, po prostu dodajesz je. Ich umieszczenie zależy całkowicie od DBMS. Właściwym miejscem, aby upewnić się, że kolumny wychodzą w odpowiedniej kolejności, jest moment, w którym Ty select
.
Innymi słowy, jeśli chcesz je w kolejności {name,colnew,qty,rate}
, użyj:
select name, colnew, qty, rate from ...
W przypadku SQLite musisz użyć alter table
, czego przykładem jest:
alter table mytable add column colnew char(50)
SELECT * FROM mytable
?
select *
w ogóle. Czasami jest to przydatne dla programów, które chcą odkrywać tabele, ale w zdecydowanej większości zastosowań powinieneś wyraźnie określać, czego chcesz, a zatem kolejność, w jakiej chcesz.
SQLite ma ograniczoną obsługę ALTER TABLE, której można użyć do dodania kolumny na końcu tabeli lub do zmiany nazwy tabeli.
Jeśli chcesz wprowadzić bardziej złożone zmiany w strukturze tabeli, musisz odtworzyć tabelę. Możesz zapisać istniejące dane do tabeli tymczasowej, upuścić starą tabelę, utworzyć nową tabelę, a następnie skopiować dane z tabeli tymczasowej.
Załóżmy na przykład, że masz tabelę o nazwie „t1” z nazwami kolumn „a” i „c” oraz że chcesz wstawić kolumnę „b” z tej tabeli. Poniższe kroki ilustrują, jak można to zrobić:
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,c);
INSERT INTO t1_backup SELECT a,c FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b, c);
INSERT INTO t1 SELECT a,c FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
Teraz możesz wstawić nowe dane w następujący sposób:
UPDATE t1 SET b='blah' WHERE a='key'
INSERT INTO t1 SELECT a,c FROM t1_backup;
powoduje błąd: „tabela t1 ma 3 kolumny, ale podano 2 wartości: WSTAWIĆ DO t1 WYBIERZ a, c Z t1_backup;”. Prawidłowa linia powinna brzmiećINSERT INTO t1 (a,c) SELECT a,c FROM t1_backup;
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
UPDATE {tableName} SET COLNew = {base on {type} pass value here};
Ta aktualizacja jest wymagana do obsługi wartości zerowej i wprowadzania wartości domyślnej zgodnie z wymaganiami. Tak jak w twoim przypadku, musisz wywołać SELECT
zapytanie, a otrzymasz kolejność kolumn, jak już powiedział paxdiablo :
SELECT name, colnew, qty, rate FROM{tablename}
i moim zdaniem, nazwa kolumny, aby uzyskać wartość z kursora:
private static final String ColNew="ColNew";
String val=cursor.getString(cursor.getColumnIndex(ColNew));
więc jeśli indeks się zmieni, aplikacja nie napotka żadnych problemów.
Jest to bezpieczny sposób w tym sensie, że w przeciwnym razie, jeśli używasz CREATE temptable
lub RENAME table
lub CREATE
, istnieje duża szansa na utratę danych, jeśli nie zostanie ostrożnie potraktowana, na przykład w przypadku, gdy transakcje występują, gdy bateria się wyczerpie.
Miałem do czynienia z tym samym problemem, a druga metoda zaproponowana w zaakceptowanej odpowiedzi, jak zauważono w komentarzach, może być problematyczna w przypadku kluczy obcych.
Moim obejściem jest wyeksportowanie bazy danych do pliku SQL, upewniając się, że instrukcje INSERT zawierają nazwy kolumn. Robię to za pomocą DB Browser for SQLite, który ma do tego przydatną funkcję. Następnie wystarczy edytować instrukcję tworzenia tabeli i wstawić nową kolumnę tam, gdzie chcesz, i ponownie utworzyć db.
W * nix podobnych systemach jest po prostu coś w stylu
cat db.sql | sqlite3 database.db
Nie wiem, jak to możliwe w przypadku bardzo dużych baz danych, ale w moim przypadku zadziałało.