Insérer une nouvelle colonne dans le tableau dans sqlite?

354

J'ai une table avec des colonnes name, qty, rate. Maintenant, je dois ajouter une nouvelle colonne COLNewentre les colonnes nameet qty. Comment ajouter une nouvelle colonne entre deux colonnes?

Testeur
la source

Réponses:

677

Vous avez deux options. Tout d'abord, vous pouvez simplement ajouter une nouvelle colonne avec les éléments suivants:

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

Deuxièmement, et plus compliqué, mais placerait la colonne où vous le souhaitez, ce serait renommer la table:

ALTER TABLE {tableName} RENAME TO TempOldTable;

Créez ensuite la nouvelle table avec la colonne manquante:

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

Et remplissez-le avec les anciennes données:

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

Supprimez ensuite l'ancienne table:

DROP TABLE TempOldTable;

Je préférerais de loin la deuxième option, car elle vous permettra de tout renommer complètement si besoin est.

Raceimaztion
la source
27
J'irais pour la première option, et utiliser l'option par défaut de l'option secend ALTER TABLE {tableName} ADD COLUMN COLNew {type} DEFAULT {defaultValue}; Plus important: (en réfléchissant à la raison pour laquelle vous souhaitez commander les colonnes ..) utilisez toujours dans chaque action d'enregistrement (comme insérer ou ajouter) toujours les noms des colonnes, de cette façon, vous n'obtiendrez jamais d'erreurs dans votre code après avoir modifié la table.
michel.iamit
5
Au fait: la valeur par défaut ne peut pas être ajoutée dans ALTER TABLE pour certains types de champs: sqlite.org/lang_altertable.html
michel.iamit
9
n'oubliez pas de recréer les index
Jan Turoň
5
vous devrez également recréer des déclencheurs
Christopher K.
7
N'oubliez pas les violations potentielles de contraintes causées par des clés étrangères: "... mais peuvent invoquer des actions de clés étrangères ou des violations de contraintes." (voir sqlite.org/foreignkeys.html#fk_schemacommands ); comme solution de contournement, vous pouvez désactiver les clés étrangères en attendant: PRAGMA foreign_keys = ON;(voir sqlite.org/foreignkeys.html#fk_enable )
Trinimon
112

Vous n'ajoutez pas de colonnes entre d' autres colonnes dans SQL, vous les ajoutez simplement. Leur emplacement dépend entièrement du SGBD. Le bon endroit pour vous assurer que les colonnes sortent dans le bon ordre est quand vous selectles.

En d'autres termes, si vous les souhaitez dans l'ordre {name,colnew,qty,rate}, vous utilisez:

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

Avec SQLite, vous devez utiliser alter table, un exemple étant:

alter table mytable add column colnew char(50)
paxdiablo
la source
2
SELECT * FROM mytable?
EML
Quelle est la valeur par défaut définie si nous ne la spécifions pas dans les lignes existantes de la nouvelle colonne?
Jacob
12
Il y a très peu de cas d'utilisation où vous devriez le faire select *. C'est parfois pratique pour les programmes qui veulent faire la découverte de tables mais, pour la grande majorité des utilisations, vous devez spécifier explicitement ce que vous voulez et donc l'ordre dans lequel vous le voulez.
paxdiablo
4
C'est fou que ce ne soit pas la "réponse acceptée". La question d'origine elle-même démontre un manque total de compréhension du fonctionnement d'un SGBDR.
Vada Poché
12

Vous pouvez ajouter une nouvelle colonne avec la requête

ALTER TABLE TableName ADD COLUMN COLNew CHAR(25)

Mais il sera ajouté à la fin, pas entre les colonnes existantes.

Mudassir
la source
11

SQLite a une prise en charge ALTER TABLE limitée que vous pouvez utiliser pour ajouter une colonne à la fin d'une table ou pour changer le nom d'une table.

Si vous souhaitez apporter des modifications plus complexes à la structure d'une table, vous devrez recréer la table. Vous pouvez enregistrer les données existantes dans une table temporaire, supprimer l'ancienne table, créer la nouvelle table, puis copier les données à partir de la table temporaire.

Par exemple, supposons que vous ayez une table nommée "t1" avec les noms de colonnes "a" et "c" et que vous souhaitiez insérer la colonne "b" de cette table. Les étapes suivantes illustrent comment cela pourrait être fait:

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;

Vous êtes maintenant prêt à insérer vos nouvelles données comme ceci:

UPDATE t1 SET b='blah' WHERE a='key'
CJH
la source
Dans mes tests, la ligne INSERT INTO t1 SELECT a,c FROM t1_backup;provoque l'erreur: "la table t1 a 3 colonnes mais 2 valeurs ont été fournies: INSERT INTO t1 SELECT a, c FROM t1_backup;". La ligne correcte devrait êtreINSERT 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};

Cette mise à jour est requise pour gérer la valeur nulle, en saisissant une valeur par défaut selon vos besoins. Comme dans votre cas, vous devez appeler la SELECTrequête et vous obtiendrez l'ordre des colonnes, comme l' a déjà dit paxdiablo :

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

et à mon avis, le nom de votre colonne pour obtenir la valeur du curseur:

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

donc si l'index change, votre application ne rencontrera aucun problème.

C'est le moyen sûr dans le sens où sinon, si vous utilisez CREATE temptableou RENAME tableou CREATE, il y aurait un risque élevé de perte de données si elles n'étaient pas traitées avec soin, par exemple dans le cas où vos transactions se produisent alors que la batterie est épuisée.

Naval Kishor Jha
la source
4

J'étais confronté au même problème et la deuxième méthode proposée dans la réponse acceptée, comme indiqué dans les commentaires, peut être problématique lorsqu'il s'agit de clés étrangères.

Ma solution consiste à exporter la base de données dans un fichier sql en m'assurant que les instructions INSERT incluent les noms de colonne. Je le fais en utilisant DB Browser pour SQLite qui a une fonctionnalité pratique pour cela. Après cela, il vous suffit de modifier l'instruction create table et d'insérer la nouvelle colonne où vous le souhaitez et de recréer la base de données.

Dans les systèmes de type * nix, c'est juste quelque chose

cat db.sql | sqlite3 database.db

Je ne sais pas dans quelle mesure cela est possible avec de très grandes bases de données, mais cela a fonctionné dans mon cas.

Hirabayashi Taro
la source