Question

Je devrais renommer quelques colonnes dans certaines tables d'une base de données SQLite. Je sais qu'une question similaire a déjà été demandé 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 sur ALTER TABLE , je suppose qu'il est impossible de le faire. chose " facilement " (c'est-à-dire une seule instruction ALTER TABLE).

Je me demandais si quelqu'un connaissait une façon générique de faire une telle chose avec SQLite.

Était-ce utile?

La solution

Ceci a été corrigé avec 2018-09-15 (3.25.0)

  

Améliorations de la ALTER TABLE commande:

     
      
  • Ajout de la prise en charge du changement de nom des colonnes dans une table à l'aide de RENAME COLUMN oldname TO newname table RENAME COLUMN TO.
  •   
  • Correction de la fonctionnalité de changement de nom 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 RENAME COLUMN

  

La syntaxe <=> 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, alors <=> échoue avec une erreur et aucune modification n'est appliquée.

 entrer la description de l'image ici 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 de db-fiddle.com

Prise en charge Android

Au moment de la rédaction de ce manuel, l'API 27 d'Android utilise le package SQLite. version 3.19 .

Sur la base de la version actuelle utilisée par Android et du fait 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 dans Android ne soit ajoutée.

Et même dans ce cas, si vous avez besoin de prendre en charge des versions plus anciennes que l'API 33, vous ne pourrez pas l'utiliser.

Autres conseils

Dites que vous avez une table et devez renommer & "; colb &"; à " col_b "

Vous commencez par renommer 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, supprimez l’ancienne table.

DROP TABLE tmp_table_name;

Envelopper tout cela dans un BEGIN TRANSACTION; et COMMIT; est également probablement une bonne idée.

S'il est vrai qu'il n'y a pas d'ALTER COLUMN, si vous souhaitez uniquement renommer la colonne, supprimer la contrainte NOT NULL ou modifier le type de données, vous pouvez utiliser le jeu de commandes suivant:

Remarque: ces commandes risquent de corrompre votre base de données. Assurez-vous donc que vous disposez d'une sauvegarde

.
PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
PRAGMA writable_schema = 0;

Vous devrez fermer et rouvrir votre connexion ou passer l'aspirateur sur la base de données pour recharger les modifications dans le schéma.

Par exemple:

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT NULL);  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
Error: BOOKS.publication_date may not be NULL  
sqlite> PRAGMA writable_schema = 1; 
sqlite> UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';  
sqlite> PRAGMA writable_schema = 0;  
sqlite> .q  

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
sqlite> .q  

RÉFÉRENCES SUIVANTES:


pragma Writable_schema
Lorsque ce pragma est activé, les tables SQLITE_MASTER dans lesquelles la base de données peut être modifiée à l'aide d'instructions UPDATE, INSERT et DELETE ordinaires. Avertissement: une mauvaise utilisation de ce pragma peut facilement entraîner la corruption du fichier de base de données.

table de modification
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.

ALTER TABLE SYNTAXE

En fouillant, j'ai trouvé cet outil graphique multiplatforme (Linux | Mac | Windows) appelé Navigateur de base de données pour 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! Voilà!

Cependant, si quelqu'un souhaite partager un moyen 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 la colonne id, lon, lat . Ainsi, lors de l’importation de la table, les valeurs de latitude étaient stockées dans la colonne lon et vice-versa. Il était donc évident que la solution la plus simple 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!

Citation de la documentation sqlite :

  

SQLite prend en charge un sous-ensemble limité de   ALTER TABLE. La commande ALTER TABLE   dans SQLite permet à l'utilisateur de renommer un   table ou pour ajouter une nouvelle colonne à un   table existante. Il n'est pas possible de renommer une colonne, de supprimer une colonne ou d'ajouter ou de supprimer des contraintes d'un tableau.

Vous pouvez bien sûr 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 une de ces choses qui me gifle avec surprise: renommer une colonne nécessite de créer une toute nouvelle table 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:

Fenêtre du journal de base

Ceux-ci peuvent ensuite être facilement copiés et collés là où vous pourriez en avoir besoin. Pour moi, cela se trouve 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.

Espérons que cela fera gagner du temps à certaines personnes.

changer la colonne de la table < id > à < _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");

Comme mentionné précédemment, il existe un outil SQLite Database Browser, qui le fait. Malheureusement, cet outil conserve 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 aide

Créez une nouvelle colonne avec le nom de colonne souhaité: COLNew.

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

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

À partir de 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 simplifiée suivante est appropriée pour supprimer les contraintes CHECK ou FOREIGN KEY ou NOT NULL, renommer les colonnes ou pour ajouter, supprimer ou modifier les valeurs par défaut d'une colonne.

  1. Démarrer une transaction.

  2. Exécutez PRAGMA version_schéma pour déterminer le numéro de version actuel du schéma. Ce numéro sera nécessaire pour l’étape 6 ci-dessous.

  3. Activez l'édition du schéma à l'aide de 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 distinct 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, apporter des modifications à 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 trouvé à l'étape 2 ci-dessus.

  7. Désactivez la modification de schéma à l'aide de 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. Validez la transaction lancée à l'étape 1 ci-dessus.

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 de votre choix, à copier le contenu dessus et à abandonner & "; " l'ancienne colonne (elle reste présente, mais vous n'utilisez pas / update, 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 qui l'ignorent risquent d'é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.

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: Anciennes versions de SQLite

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 modifier le nom de la colonne Location

Étape 1: renommer la table d'origine:

ALTER TABLE student RENAME TO student_temp;

Étape 2: créez maintenant 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;

Ces quatre étapes vous permettent de 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.

Depuis la version 2018-09-15 (3.25.0) sqlite prend en charge le changement de nom des colonnes

https://sqlite.org/changes.html

sqlite3 yourdb .dump > /tmp/db.txt
edit /tmp/db.txt change le nom de la colonne dans la ligne Créer

sqlite2 yourdb2 < /tmp/db.txt
mv / move yourdb2 yourdb

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top