web-dev-qa-db-fra.com

Comment renommer une colonne dans une table de base de données SQLite?

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.

278
joce

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.

enter image description here 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;
_

démo db-fiddle.com


Support Android

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.

41
Lukasz Szozda

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.

438
Evan

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!

55
joce

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!

18
aizquier

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.

12
Elazar Leibovich

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:

Base log window

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.

7
Joshua Pinter

change la colonne de la table <id> en <_id>

 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
Vahe Gharibyan

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

2
Chris Lytridis

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.

2
Anthony Ebert

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.

  1. Lancer une transaction.

  2. 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.

  3. Activez l’édition du schéma en utilisant PRAGMA writeable_schema = ON.

  4. 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.

  5. 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.

  6. 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.

  7. Désactivez l'édition du schéma en utilisant PRAGMA writeable_schema = OFF.

  8. (Facultatif) Exécutez PRAGMA Integrity_check pour vérifier que les modifications de schéma n'ont pas endommagé la base de données.

  9. Commettez la transaction commencée à l'étape 1 ci-dessus.

2
Mohammad Yahia

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.

1
Febin Mathew

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.

1
rogerdpack

Depuis la version 2018-09-15 (3.25.0), sqlite prend en charge le renommage de colonnes.

https://sqlite.org/changes.html

0
RusAlex