J'aurais besoin de renommer quelques colonnes dans certaines tables d'une base de données SQLite. Je sais qu'une question similaire a déjà été posée sur stackoverflow, mais c'était pour SQL en général, et le cas de SQLite n'a pas été mentionné.
D'après la documentation de SQLite pour ALTER TABLE , je suppose qu'il n'est pas possible de faire une telle chose "facilement" (c'est-à-dire une seule instruction ALTER TABLE).
Je me demandais si quelqu'un connaissait une façon générique SQL de faire une telle chose avec SQLite.
Cela vient d'être corrigé avec 2018-09-15 (3.25.0)
Améliorations de la commande _
ALTER TABLE
_:
- Ajout du support pour renommer des colonnes dans une table à l'aide de _
ALTER TABLE
_ table _RENAME COLUMN oldname TO newname
_.- Correction de la fonctionnalité de renommage de table afin qu'elle mette également à jour les références à la table renommée dans les déclencheurs et les vues.
Vous pouvez trouver la nouvelle syntaxe documentée sous ALTER TABLE
La syntaxe _
RENAME COLUMN TO
_ change le nom de colonne de la table nom de table en nouveau nom de colonne. Le nom de la colonne est modifié à la fois dans la définition de table et dans tous les index, déclencheurs et vues faisant référence à la colonne. Si le changement de nom de colonne entraîne une ambiguïté sémantique dans un déclencheur ou une vue, le _RENAME COLUMN
_ échoue avec une erreur et aucune modification n'est appliquée.
Source de l'image: https://www.sqlite.org/images/syntax/alter-table-stmt.gif
Exemple:
_CREATE TABLE tab AS VALUES(1);
SELECT * FROM tab;
ALTER TABLE tab RENAME TO tab_new;
SELECT * FROM tab_new;
_
Au moment de l'écriture, l'API 27 d'Android utilise la version 3.19 du paquet SQLite .
D'après la version actuelle utilisée par Android et que cette mise à jour est fournie dans la version 3.25.0 de SQLite, je dirais que vous devez attendre un peu (environ l'API 33) avant que la prise en charge de cette mise à jour ne soit ajoutée à Android.
Et même dans ce cas, si vous avez besoin de prendre en charge des versions antérieures à l'API 33, vous ne pourrez pas l'utiliser.
Supposons que vous ayez une table et devez renommer "colb" en "col_b":
D'abord, vous renommez l'ancienne table:
ALTER TABLE orig_table_name RENAME TO tmp_table_name;
Créez ensuite la nouvelle table, basée sur l'ancienne table mais avec le nom de colonne mis à jour:
CREATE TABLE orig_table_name (
col_a INT
, col_b INT
);
Copiez ensuite le contenu en face de la table d'origine.
INSERT INTO orig_table_name(col_a, col_b)
SELECT col_a, colb
FROM tmp_table_name;
Enfin, laissez tomber la vieille table.
DROP TABLE tmp_table_name;
Envelopper tout cela dans un BEGIN TRANSACTION;
et COMMIT;
est également probablement une bonne idée.
En fouillant, j'ai trouvé cet outil graphique multiplateforme (Linux | Mac | Windows) appelé DB Browser for SQLite qui permet de renommer les colonnes de manière très conviviale!
Modifier | Modifier la table | Sélectionnez la table | Modifier le champ. Cliquez, cliquez! Voila!
Cependant, si quelqu'un souhaite partager une manière programmatique de le faire, je serais heureux de le savoir!
Récemment, j’ai dû faire cela dans SQLite3 avec une table nommée points avec les colonnes id, lon, lat. Ainsi, lorsque la table a été importée, les valeurs de latitude ont été stockées dans la colonne lon et vice-versa, de sorte qu'un correctif évident serait de renommer ces colonnes. Donc le truc était:
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;
J'espère que cela vous sera utile!
Citant le documentation sqlite :
SQLite prend en charge un sous-ensemble limité d'ALTER TABLE. La commande ALTER TABLE dans SQLite permet à l'utilisateur de renommer une table ou d'ajouter une nouvelle colonne à une table existante. Il n'est pas possible de renommer une colonne, de supprimer une colonne ou d'ajouter ou de supprimer des contraintes d'une table.
Bien sûr, vous pouvez créer un nouveau tableau avec la nouvelle présentation SELECT * FROM old_table
et remplir le nouveau tableau avec les valeurs que vous recevrez.
Tout d'abord, c'est l'une de ces choses qui me gifle avec surprise: renommer une colonne nécessite de créer une table entièrement nouvelle et de copier les données de l'ancienne table dans la nouvelle table. ..
L’interface graphique sur laquelle j’ai atterri pour effectuer des opérations SQLite est Base . Il a une fenêtre de journal astucieuse qui montre toutes les commandes qui ont été exécutées. Renommer une colonne via Base remplit la fenêtre du journal avec les commandes nécessaires:
Ceux-ci peuvent ensuite être facilement copiés et collés où vous pourriez en avoir besoin. Pour moi, c'est dans un fichier de migration ActiveAndroid . Il est également intéressant de noter que les données copiées incluent uniquement les commandes SQLite, pas les horodatages, etc.
J'espère que cela fait gagner du temps à certaines personnes.
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");
Comme mentionné précédemment, il existe un outil SQLite Database Browser, qui le fait. Malheureusement, cet outil tient un journal de toutes les opérations effectuées par l'utilisateur ou l'application. En faisant cela une fois et en regardant le journal de l'application, vous verrez le code impliqué. Copiez la requête et collez-la au besoin. Travaillé pour moi J'espère que cela t'aides
Créez une nouvelle colonne avec le nom de colonne souhaité: COLNew.
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
Copier le contenu de l'ancienne colonne COLOld dans la nouvelle colonne COLNew.
INSERT INTO {tableName} (COLNew) SELECT {COLOld} FROM {tableName}
Remarque: les crochets sont nécessaires dans la ligne ci-dessus.
d'après la documentation officielle
Une procédure plus simple et plus rapide peut éventuellement être utilisée pour certaines modifications qui n'affectent en aucune façon le contenu sur le disque. La procédure plus simple suivante est appropriée pour supprimer les contraintes CHECK ou FOREIGN KEY ou NOT NULL, renommer des colonnes , ou ajouter, supprimer ou modifier les valeurs par défaut d'une colonne.
Lancer une transaction.
Exécutez PRAGMA version_schéma pour déterminer le numéro de version du schéma actuel. Ce numéro sera nécessaire pour l'étape 6 ci-dessous.
Activez l’édition du schéma en utilisant PRAGMA writeable_schema = ON.
Exécutez une instruction UPDATE pour modifier la définition de la table X dans la table sqlite_master: UPDATE sqlite_master SET sql = ... WHERE type = 'table' AND nom = 'X';
Attention: Si vous modifiez la table sqlite_master de cette manière, la base de données sera corrompue et illisible si la modification contient une erreur de syntaxe. Il est suggéré de tester soigneusement l’instruction UPDATE sur une base de données vierge distincte avant de l’utiliser sur une base de données contenant des données importantes.
Si la modification de la table X affecte également d'autres tables ou index ou si les déclencheurs sont des vues dans le schéma, exécutez les instructions UPDATE pour modifier également ces autres index et vues de table. Par exemple, si le nom d'une colonne change, toutes les contraintes, déclencheurs, index et vues de FOREIGN KEY faisant référence à cette colonne doivent être modifiés.
Attention: Une fois encore, modifier la table sqlite_master de la sorte rendra la base de données corrompue et illisible si la modification contient une erreur. Testez soigneusement l'ensemble de cette procédure sur une base de données de test séparée avant de l'utiliser sur une base de données contenant des données importantes et/ou effectuez des copies de sauvegarde de bases de données importantes avant d'exécuter cette procédure.
Incrémentez le numéro de version du schéma à l'aide de PRAGMA schema_version = X où X est égal à un de plus que l'ancien numéro de version du schéma indiqué à l'étape 2 ci-dessus.
Désactivez l'édition du schéma en utilisant PRAGMA writeable_schema = OFF.
(Facultatif) Exécutez PRAGMA Integrity_check pour vérifier que les modifications de schéma n'ont pas endommagé la base de données.
Commettez la transaction commencée à l'étape 1 ci-dessus.
CAS 1: SQLite 3.25.0 +
Seule la version 3.25.0 de SQLite prend en charge le changement de nom des colonnes. Si votre appareil répond à cette exigence, les choses sont assez simples. La requête ci-dessous résoudrait votre problème:
ALTER TABLE "MyTable" RENAME COLUMN "OldColumn" TO "NewColumn";
CAS 2: SQLite Anciennes Versions
Vous devez suivre une approche différente pour obtenir le résultat qui pourrait être un peu délicat
Par exemple, si vous avez une table comme celle-ci:
CREATE TABLE student(Name TEXT, Department TEXT, Location TEXT)
Et si vous souhaitez changer le nom de la colonne Location
Étape 1: Renommez la table d'origine:
ALTER TABLE student RENAME TO student_temp;
Étape 2: Maintenant créez une nouvelle table student
avec le nom de colonne correct:
CREATE TABLE student(Name TEXT, Department TEXT, Address TEXT)
Étape 3: Copiez les données de la table d'origine dans la nouvelle table:
INSERT INTO student(Name, Department, Address) SELECT Name, Department, Location FROM student_temp;
Remarque: la commande ci-dessus doit comporter une seule ligne.
Étape 4: Supprimer le tableau d'origine:
DROP TABLE student_temp;
Avec ces quatre étapes, vous pouvez modifier manuellement n’importe quelle table SQLite. N'oubliez pas que vous devrez également recréer tous les index, visualiseurs ou déclencheurs de la nouvelle table.
Une option, si vous en avez besoin d'une manière pincée et si votre colonne initiale a été créée avec une valeur par défaut, consiste à créer la nouvelle colonne souhaitée, à y copier le contenu et à "abandonner" l'ancienne colonne (elle reste présent, mais vous ne l'utilisez pas/le mettez à jour, etc.)
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
Cela laisse une colonne (et si elle a été créée avec NOT NULL mais sans valeur par défaut, les insertions futures l'ignorant pourraient échouer), mais s'il s'agit simplement d'une table jetable, les compromis pourraient être acceptables. Sinon, utilisez l'une des autres réponses mentionnées ici ou une autre base de données permettant de renommer des colonnes.
Depuis la version 2018-09-15 (3.25.0), sqlite prend en charge le renommage de colonnes.