Neue Spalte in SQLite in Tabelle einfügen?

354

Ich habe eine Tabelle mit Spalten name, qty, rate. Jetzt muss ich eine neue Spalte COLNewzwischen den Spalten nameund hinzufügen qty. Wie füge ich eine neue Spalte zwischen zwei Spalten hinzu?

Prüfer
quelle

Antworten:

677

Sie haben zwei Möglichkeiten. Zunächst können Sie einfach eine neue Spalte mit den folgenden Angaben hinzufügen:

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

Zweitens und komplizierter, aber würde die Spalte tatsächlich dort platzieren, wo Sie es möchten, wäre es, die Tabelle umzubenennen:

ALTER TABLE {tableName} RENAME TO TempOldTable;

Erstellen Sie dann die neue Tabelle mit der fehlenden Spalte:

CREATE TABLE {tableName} (name TEXT, COLNew {type} DEFAULT {defaultValue}, qty INTEGER, rate REAL);

Und füllen Sie es mit den alten Daten:

INSERT INTO {tableName} (name, qty, rate) SELECT name, qty, rate FROM TempOldTable;

Dann löschen Sie die alte Tabelle:

DROP TABLE TempOldTable;

Ich würde die zweite Option sehr bevorzugen, da Sie damit bei Bedarf alles komplett umbenennen können.

Raceimaztion
quelle
26
Ich würde mich für die erste Option entscheiden und die Standardoption aus der zweiten Option verwenden. ALTER TABLE {tableName} ADD COLUMN COLNew {type} DEFAULT {defaultValue}; Wichtiger: (Überlegen Sie, warum Sie die Spalten bestellen möchten.) Verwenden Sie in jeder Datensatzaktion (wie Einfügen oder Hinzufügen) immer die Spaltennamen. Auf diese Weise erhalten Sie nach dem Ändern der Tabelle niemals Fehler in Ihrem Code.
michel.iamit
5
Übrigens: Standardwert kann in ALTER TABLE für einige Feldtypen nicht hinzugefügt werden: sqlite.org/lang_altertable.html
michel.iamit
9
Vergessen Sie nicht, Indizes neu zu erstellen
Jan Turoň
5
Sie müssen auch Trigger neu erstellen
Christopher K.
7
Vergessen Sie nicht mögliche durch Fremdschlüssel verursachte Einschränkungsverletzungen: "... können jedoch Fremdschlüsselaktionen oder Einschränkungsverletzungen auslösen." (siehe sqlite.org/foreignkeys.html#fk_schemacommands ); Als Problemumgehung können Sie Fremdschlüssel in der Zwischenzeit deaktivieren: PRAGMA foreign_keys = ON;(siehe sqlite.org/foreignkeys.html#fk_enable )
Trinimon
112

Sie fügen keine Spalten zwischen anderen Spalten in SQL hinzu, sondern fügen sie nur hinzu. Wo sie hingelegt werden, liegt ganz beim DBMS. Der richtige Ort, um sicherzustellen, dass die Spalten in der richtigen Reihenfolge angezeigt werden, ist bei Ihnenselect sie haben.

Mit anderen Worten, wenn Sie sie in der Reihenfolge haben möchten {name,colnew,qty,rate}, verwenden Sie:

select name, colnew, qty, rate from ...

Mit SQLite müssen Sie Folgendes verwenden alter table: Ein Beispiel ist:

alter table mytable add column colnew char(50)
paxdiablo
quelle
2
SELECT * FROM mytable?
EML
Was ist der Standardwert, der festgelegt wird, wenn er nicht in vorhandenen Zeilen einer neuen Spalte angegeben wird?
Jacob
12
Es gibt nur sehr wenige Anwendungsfälle, in denen Sie überhaupt etwas tun sollten select *. Es ist manchmal praktisch für Programme, die Tabellen ermitteln möchten, aber für die meisten Verwendungszwecke sollten Sie explizit angeben, was Sie möchten und daher die Reihenfolge, in der Sie es möchten.
Paxdiablo
4
Es ist verrückt, dass dies nicht die "akzeptierte Antwort" ist. Die ursprüngliche Frage selbst zeigt einen völligen Mangel an Verständnis für die Funktionsweise eines RDBMS.
Vada Poché
12

Sie können der Abfrage eine neue Spalte hinzufügen

ALTER TABLE TableName ADD COLUMN COLNew CHAR(25)

Es wird jedoch am Ende hinzugefügt, nicht zwischen den vorhandenen Spalten.

Mudassir
quelle
11

SQLite bietet nur eingeschränkte Unterstützung für ALTER TABLE, mit der Sie eine Spalte am Ende einer Tabelle hinzufügen oder den Namen einer Tabelle ändern können.

Wenn Sie komplexere Änderungen an der Struktur einer Tabelle vornehmen möchten, müssen Sie die Tabelle neu erstellen. Sie können vorhandene Daten in einer temporären Tabelle speichern, die alte Tabelle löschen, die neue Tabelle erstellen und die Daten dann wieder aus der temporären Tabelle kopieren.

Angenommen, Sie haben eine Tabelle mit dem Namen "t1" mit den Spaltennamen "a" und "c" und möchten die Spalte "b" aus dieser Tabelle einfügen. Die folgenden Schritte veranschaulichen, wie dies getan werden kann:

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;

Jetzt können Sie Ihre neuen Daten wie folgt einfügen:

UPDATE t1 SET b='blah' WHERE a='key'
CJH
quelle
In meinen Tests INSERT INTO t1 SELECT a,c FROM t1_backup;verursacht die Zeile den Fehler: "Tabelle t1 hat 3 Spalten, aber 2 Werte wurden angegeben: INSERT IN t1 SELECT a, c FROM t1_backup;". Die richtige Zeile sollte seinINSERT INTO t1 (a,c) SELECT a,c FROM t1_backup;
JnLlnd
5
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
UPDATE {tableName} SET COLNew = {base on {type} pass value here};

Dieses Update ist erforderlich, um den Nullwert zu verarbeiten und nach Bedarf einen Standardwert einzugeben. Wie in Ihrem Fall müssen Sie die SELECTAbfrage aufrufen und erhalten die Reihenfolge der Spalten, wie paxdiablo bereits sagte:

SELECT name, colnew, qty, rate FROM{tablename}

und meiner Meinung nach Ihr Spaltenname, um den Wert vom Cursor zu erhalten:

private static final String ColNew="ColNew";
String val=cursor.getString(cursor.getColumnIndex(ColNew));

Wenn sich der Index ändert, treten bei Ihrer Anwendung keine Probleme auf.

Dies ist der sichere Weg in dem Sinne, dass andernfalls bei Verwendung CREATE temptableoder RENAME tableoder CREATEeine hohe Wahrscheinlichkeit eines Datenverlusts besteht, wenn er nicht sorgfältig behandelt wird, z. B. wenn Ihre Transaktionen stattfinden, während der Akku leer ist.

Marine Kishor Jha
quelle
4

Ich hatte das gleiche Problem und die zweite in der akzeptierten Antwort vorgeschlagene Methode, wie in den Kommentaren angegeben, kann beim Umgang mit Fremdschlüsseln problematisch sein.

Meine Problemumgehung besteht darin, die Datenbank in eine SQL-Datei zu exportieren und sicherzustellen, dass die INSERT-Anweisungen Spaltennamen enthalten. Ich mache es mit DB Browser für SQLite der eine praktische Funktion dafür hat. Danach müssen Sie nur noch die Anweisung create table bearbeiten und die neue Spalte an der gewünschten Stelle einfügen und die Datenbank neu erstellen.

In * nix-ähnlichen Systemen ist nur etwas in der Art von

cat db.sql | sqlite3 database.db

Ich weiß nicht, wie machbar dies mit sehr großen Datenbanken ist, aber es hat in meinem Fall funktioniert.

Hirabayashi Taro
quelle