¿Cómo cambio el nombre de una columna en una tabla de base de datos SQLite?

StackOverflow https://stackoverflow.com/questions/805363

  •  03-07-2019
  •  | 
  •  

Pregunta

Necesitaría cambiar el nombre de algunas columnas en algunas tablas de una base de datos SQLite.sé que un pregunta similar Se preguntó anteriormente en stackoverflow, pero era para SQL en general y no se mencionó el caso de SQLite.

De la documentación de SQLite para ALTERAR TABLA, Deduzco que no es posible hacer tal cosa "fácilmente" (es decir,una sola instrucción ALTER TABLE).

Me preguntaba que alguien conocía una forma SQL genérica de hacer tal cosa con SQLite.

¿Fue útil?

Solución

Esto se solucionó con 2018-09-15 (3.25.0)

  

Mejoras en el comando ALTER TABLE:

     
      
  • Agregue soporte para renombrar columnas dentro de una tabla usando RENAME COLUMN oldname TO newname tabla RENAME COLUMN TO.
  •   
  • Se corrigió la función de cambio de nombre de la tabla para que también actualice las referencias a la tabla renombrada en activadores y vistas.
  •   

Puede encontrar la nueva sintaxis documentada en RENAME COLUMN

  

La sintaxis <=> cambia el nombre de columna de la tabla nombre-tabla en nombre-nueva-columna. El nombre de la columna se cambia tanto en la definición de la tabla como en todos los índices, desencadenantes y vistas que hacen referencia a la columna. Si el cambio de nombre de columna daría lugar a una ambigüedad semántica en un disparador o vista, entonces el <=> falla con un error y no se aplican cambios.

 ingrese la descripción de la imagen aquí Fuente de la imagen: https://www.sqlite.org/images /syntax/alter-table-stmt.gif

Ejemplo:

CREATE TABLE tab AS VALUES(1);

SELECT * FROM tab;

ALTER TABLE tab RENAME TO tab_new;

SELECT * FROM tab_new;

db-fiddle.com demo


Soporte de Android

Al momento de escribir, la API 27 de Android está usando el paquete SQLite versión 3.19 .

Basado en la versión actual que está usando Android y que esta actualización viene en la versión 3.25.0 de SQLite, diría que tiene que esperar un poco (aproximadamente API 33) antes de que se agregue soporte para Android.

Y, aun así, si necesita admitir versiones anteriores a la API 33, no podrá utilizarlo.

Otros consejos

Supongamos que tiene una tabla y necesita cambiar el nombre de "colb" a "col_b":

Primero cambias el nombre de la tabla anterior:

ALTER TABLE orig_table_name RENAME TO tmp_table_name;

Luego cree la nueva tabla, basada en la tabla anterior pero con el nombre de columna actualizado:

CREATE TABLE orig_table_name (
  col_a INT
, col_b INT
);

Luego copie el contenido frente a la tabla original.

INSERT INTO orig_table_name(col_a, col_b)
SELECT col_a, colb
FROM tmp_table_name;

Por último, suelta la mesa vieja.

DROP TABLE tmp_table_name;

Envolviendo todo esto en un BEGIN TRANSACTION; y COMMIT; Probablemente también sea una buena idea.

Si bien es cierto que no existe ALTER COLUMN, si solo desea cambiar el nombre de la columna, descartar la restricción NOT NULL o cambiar el tipo de datos, puede utilizar el siguiente conjunto de comandos:

Nota: estos comandos tienen el potencial de dañar su base de datos, así que asegúrese de tener una copia de seguridad

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;

Deberá cerrar y volver a abrir su conexión o aspirar la base de datos para volver a cargar los cambios en el esquema.

Por ejemplo:

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  

REFERENCIAS SIGUEN:


pragma writable_schema
Cuando este pragma está activado, las tablas SQLITE_MASTER en las que la base de datos se puede cambiar mediante las instrucciones ordinarias UPDATE, INSERT y DELETE. Advertencia: el mal uso de este pragma puede resultar fácilmente en un archivo de base de datos corrupto.

alter table
SQLite admite un subconjunto limitado de ALTER TABLE. El comando ALTER TABLE en SQLite permite al usuario cambiar el nombre de una tabla o agregar una nueva columna a una tabla existente. No es posible cambiar el nombre de una columna, eliminar una columna o agregar o eliminar restricciones de una tabla.

ALTERAR SINTAXIS DE TABLA

Excavando, encontré esta herramienta gráfica multiplataforma (Linux | Mac | Windows) llamada DB Browser para SQLite que en realidad ¡permite cambiar el nombre de las columnas de una manera muy fácil de usar!

Editar | Modificar tabla | Seleccionar tabla | Editar campo. ¡Clic clic! ¡Voila!

Sin embargo, si alguien quiere compartir una forma programática de hacer esto, ¡me encantaría saberlo!

Recientemente tuve que hacer eso en SQLite3 con una tabla llamada puntos con las columnas id, lon, lat . Por error, cuando se importó la tabla, los valores de latitud se almacenaron en la columna lon y viceversa, por lo que una solución obvia sería cambiar el nombre de esas columnas. Entonces el truco fue:

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;

¡Espero que esto te sea útil!

Citando el documentación sqlite:

SQLite admite un subconjunto limitado de Tabla Alter.El comando ALTER TABLE en SQLite permite al usuario cambiar el nombre de una tabla o agregar una nueva columna a una tabla existente. No es posible cambiar el nombre de una columna, eliminar una columna ni agregar o eliminar restricciones de una tabla.

Lo que puedes hacer, por supuesto, es crear una nueva tabla con el nuevo diseño, SELECT * FROM old_table, y complete la nueva tabla con los valores que recibirá.

En primer lugar, esta es una de esas cosas que me sorprende en la cara: cambiar el nombre de una columna requiere crear una tabla completamente nueva y copiar los datos de la tabla anterior a la nueva tabla ...

La GUI en la que he aterrizado para realizar operaciones SQLite es Base . Tiene una ingeniosa ventana de registro que muestra todos los comandos que se han ejecutado. Al cambiar el nombre de una columna a través de Base, se llena la ventana de registro con los comandos necesarios:

Ventana de registro base

Estos se pueden copiar y pegar fácilmente donde los necesite. Para mí, eso está en un ActiveAndroid archivo de migración. Un buen detalle también es que los datos copiados solo incluyen los comandos SQLite, no las marcas de tiempo, etc.

Con suerte, eso ahorra tiempo a algunas personas.

cambiar la columna de la tabla < id > a < _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");

Como se mencionó anteriormente, existe una herramienta SQLite Database Browser, que hace esto. Afortunadamente, esta herramienta mantiene un registro de todas las operaciones realizadas por el usuario o la aplicación. Al hacer esto una vez y mirar el registro de la aplicación, verá el código involucrado. Copie la consulta y péguela según sea necesario. Trabajó para mi. Espero que esto ayude

Cree una nueva columna con el nombre de columna deseado: COLNew.

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

Copie el contenido de la antigua columna COLOld a la nueva columna COLNew.

INSERT INTO {tableName} (COLNew) SELECT {COLOld} FROM {tableName}

Nota: los corchetes son necesarios en la línea anterior.

De la documentación oficial

Un procedimiento más simple y rápido se puede usar opcionalmente para algunos cambios que no afectan el contenido del disco de ninguna manera. El siguiente procedimiento más sencillo es apropiado para eliminar las restricciones CHECK o FOREIGN KEY o NOT NULL, renombrar columnas , o agregar o eliminar o cambiar los valores predeterminados en una columna.

  1. Iniciar una transacción.

  2. Ejecute PRAGMA schema_version para determinar el número de versión del esquema actual. Este número será necesario para el paso 6 a continuación.

  3. Active la edición de esquemas usando PRAGMA writable_schema = ON.

  4. Ejecute una instrucción UPDATE para cambiar la definición de la tabla X en la tabla sqlite_master: UPDATE sqlite_master SET sql = ... WHERE type = 'table' AND name = 'X';

    Precaución: Realizar un cambio en la tabla sqlite_master como esta hará que la base de datos se corrompa e ilegible si el cambio contiene un error de sintaxis. Se sugiere que las pruebas cuidadosas de la declaración ACTUALIZACIÓN se realicen en una base de datos en blanco separada antes de usarla en una base de datos que contenga datos importantes.

  5. Si el cambio a la tabla X también afecta a otras tablas o índices o los desencadenantes son vistas dentro del esquema, ejecute las instrucciones UPDATE para modificar esos índices y vistas de otras tablas también. Por ejemplo, si cambia el nombre de una columna, se deben modificar todas las restricciones, desencadenantes, índices y vistas de FOREIGN KEY que se refieren a esa columna.

    Precaución: una vez más, realizar cambios en la tabla sqlite_master de esta manera hará que la base de datos esté corrupta e ilegible si el cambio contiene un error. Pruebe cuidadosamente todo este procedimiento en una base de datos de prueba separada antes de usarlo en una base de datos que contenga datos importantes y / o haga copias de seguridad de bases de datos importantes antes de ejecutar este procedimiento.

  6. Incremente el número de versión del esquema usando PRAGMA schema_version = X donde X es uno más que el número de versión del esquema anterior encontrado en el paso 2 anterior.

  7. Desactiva la edición de esquemas usando PRAGMA writable_schema = OFF.

  8. (Opcional) Ejecute PRAGMA integridad_check para verificar que los cambios en el esquema no dañaron la base de datos.

  9. Confirma la transacción iniciada en el paso 1 anterior.

Una opción, si necesita hacerlo en un apuro, y si su columna inicial se creó con un valor predeterminado, es crear la nueva columna que desee, copiar el contenido y básicamente " abandonar " la columna anterior (permanece presente, pero simplemente no la usa / actualiza, 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

Esto deja una columna (y si se creó con NOT NULL pero sin un valor predeterminado, entonces las inserciones futuras que lo ignoren podrían fallar), pero si es solo una tabla desechable, las compensaciones podrían ser aceptables. De lo contrario, use una de las otras respuestas mencionadas aquí, o una base de datos diferente que permita cambiar el nombre de las columnas.

CASO 1: SQLite 3.25.0+

Solo la versión 3.25.0 de SQLite admite cambiar el nombre de las columnas. Si su dispositivo cumple con este requisito, las cosas son bastante simples. La consulta a continuación resolvería su problema:

ALTER TABLE "MyTable" RENAME COLUMN "OldColumn" TO "NewColumn";

CASO 2: Versiones anteriores de SQLite

Debe seguir un Enfoque diferente para obtener el resultado, que puede ser un poco complicado

Por ejemplo, si tiene una tabla como esta:

CREATE TABLE student(Name TEXT, Department TEXT, Location TEXT)

Y si desea cambiar el nombre de la columna Location

Paso 1: Cambie el nombre de la tabla original:

ALTER TABLE student RENAME TO student_temp;

Paso 2: ahora cree una nueva tabla student con el nombre de columna correcto:

CREATE TABLE student(Name TEXT, Department TEXT, Address TEXT)

Paso 3: Copie los datos de la tabla original a la nueva tabla:

INSERT INTO student(Name, Department, Address) SELECT Name, Department, Location FROM student_temp;

Nota: El comando anterior debe ser una sola línea.

Paso 4: Suelte la tabla original:

DROP TABLE student_temp;

Con estos cuatro pasos puede cambiar manualmente cualquier tabla SQLite. Tenga en cuenta que también necesitará recrear cualquier índice, visor o activador en la nueva tabla también.

Desde la versión 2018-09-15 (3.25.0) sqlite admite renombrar columnas

https://sqlite.org/changes.html

sqlite3 yourdb .dump > /tmp/db.txt
edite /tmp/db.txt cambie el nombre de la columna en Crear línea
sqlite2 yourdb2 < /tmp/db.txt
mv / move yourdb2 yourdb

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top