update not drop columns column after sqlite alter-table

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



sqlite alter table drop column (13)

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

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

Me preguntaba si alguien sabía de una forma genérica de SQL para hacer tal cosa con SQLite.


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");


Citando la documentación de sqlite :

SQLite soporta 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.

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


Como se mencionó anteriormente, hay una herramienta SQLite Database Browser, que hace esto. Lyckily, esta herramienta mantiene un registro de todas las operaciones realizadas por el usuario o la aplicación. Haciendo esto una vez y mirando el registro de la aplicación, verá el código involucrado. Copie la consulta y pegue 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 columna antigua COLOld a la nueva columna COLNew.

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

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


Digamos que tienes una tabla y necesitas cambiar el nombre de "colb" a "col_b":

Primero cambia 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 copia los contenidos a través de la tabla original.

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

Por último, dejar caer la vieja mesa.

DROP TABLE tmp_table_name;

Envolviendo todo esto en una BEGIN TRANSACTION; y COMMIT; También es probablemente una buena idea.


Esto se acaba de arreglar con 2018-09-15 (3.25.0)

Mejoras el comando ALTER TABLE :

  • Agregue soporte para cambiar el nombre de columnas dentro de una tabla utilizando la tabla ALTER TABLE RENAME COLUMN oldname TO newname .
  • Arreglar la función de cambio de nombre de la tabla para que también actualice las referencias a la tabla a la que se le ha cambiado el nombre en activadores y vistas.

Puede encontrar la nueva sintaxis documentada en ALTER TABLE

La sintaxis RENAME COLUMN TO cambia el nombre de columna de la tabla nombre de tabla al nombre de nueva columna. El nombre de la columna se cambia tanto dentro de la definición de la tabla como en todos los índices, activadores y vistas que hacen referencia a la columna. Si el cambio de nombre de la columna resultaría en una ambigüedad semántica en un desencadenante o vista, entonces RENAME COLUMN falla con un error y no se aplican cambios.

Fuente de la imagen: https://www.sqlite.org/images/syntax/alter-table-stmt.gif


Rebuscando, encontré esta herramienta gráfica multiplataforma (Linux | Mac | Windows) llamada DB Browser for SQLite que realmente 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 points con los colunms id, lon, lat . De forma errónea, 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. Así que 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 de utilidad!


Si bien es cierto que no hay ALTER COLUMN, si solo desea cambiar el nombre de la columna, eliminar la restricción NOT NULL o cambiar el tipo de datos, puede usar 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 pasar la base de datos de 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

Las referencias siguen:

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

alterar tabla
SQLite soporta 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.


Una opción, si necesita hacerlo en un pellizco, y si su columna inicial se creó con un valor predeterminado, es crear la nueva columna que desea, copiar el contenido a ella y básicamente "abandonar" la columna anterior (permanece presente, pero simplemente no lo 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 futuras inserciones que ignoren podrían fallar), pero si es solo una tabla desechable, las compensaciones pueden ser aceptables. De lo contrario, utilice una de las otras respuestas mencionadas aquí, o una base de datos diferente que permita cambiar el nombre de las columnas.


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


De la documentación oficial.

Opcionalmente, se puede usar un procedimiento más simple y rápido para algunos cambios que no afectan el contenido en disco de ninguna manera. El siguiente procedimiento más simple es adecuado para eliminar las restricciones CHECK o FOREIGN KEY o NOT NULL, cambiar el nombre de las columnas , agregar o eliminar o cambiar los valores predeterminados de 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 utilizando 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 = ... DONDE tipo = ''tabla'' AND nombre = ''X'';

    Precaución: si se realiza un cambio en la tabla sqlite_master de esta forma, la base de datos se volverá corrupta e ilegible si el cambio contiene un error de sintaxis. Se sugiere que se realice una prueba cuidadosa de la declaración UPDATE 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, los índices o los activadores son vistas dentro del esquema, entonces ejecute las instrucciones UPDATE para modificar esos otros índices de tablas y también las vistas. Por ejemplo, si el nombre de una columna cambia, se deben modificar todas las restricciones, activadores, índices y vistas de FOREIGN KEY que se refieren a esa columna.

    Precaución: una vez más, hacer cambios en la tabla sqlite_master de esta manera hará que la base de datos sea corrupta e ilegible si el cambio contiene un error. Pruebe cuidadosamente todo este procedimiento en una base de datos de prueba por separado antes de usarlo en una base de datos que contenga datos importantes y / o haga copias de respaldo 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 que se encuentra en el paso 2 anterior.

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

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

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


En primer lugar, esta es una de esas cosas que me da una bofetada de sorpresa: cambiar el nombre de una columna requiere crear una tabla completamente nueva y copiar los datos de la tabla antigua a la tabla nueva ...

La GUI en la que he aterrizado para realizar operaciones de 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 la Base, se completa la ventana de registro con los comandos necesarios:

Estos se pueden copiar y pegar fácilmente donde los necesite. Para mí, eso es en un archivo de migración ActiveAndroid . Un toque agradable, 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.