tablas relacionadas registros eliminar ejemplos delete cascada java android sqlite foreign-keys

java - relacionadas - on delete cascade



¿Restricciones de clave foránea en Android usando SQLite? en Eliminar cascada (9)

Como la publicación de e.shishkin dice desde la API 16, debe habilitar las restricciones de clave externa en el SqLiteOpenHelper.onConfigure(SqLiteDatabase) utilizando db.setForeignKeyConstraintsEnabled(boolean)

@Override public void onConfigure(SQLiteDatabase db){ db.setForeignKeyConstraintsEnabled(true); }

Tengo dos tablas: tracks y waypoints, una pista puede tener muchos waypoints, pero un waypoint está asignado a solo 1 pista.

En la tabla de puntos de camino, tengo una columna llamada "trackidfk" que inserta el track_ID una vez que se realiza una pista, sin embargo, no he configurado restricciones de clave foránea en esta columna.

Cuando elimino una pista, quiero eliminar los puntos de referencia asignados, ¿es esto posible? Leí sobre el uso de Triggers, pero no creo que sean compatibles con Android.

Para crear la tabla de puntos de referencia:

public void onCreate(SQLiteDatabase db) { db.execSQL( "CREATE TABLE " + TABLE_NAME + " (" + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + LONGITUDE + " INTEGER," + LATITUDE + " INTEGER," + TIME + " INTEGER," + TRACK_ID_FK + " INTEGER" + " );" ); ... }


Desde Android 4.1 (API 16) SQLiteDatabase compatible con:

public void setForeignKeyConstraintsEnabled (boolean enable)


La versión de SQLite en Android 1.6 es 3.5.9 por lo que no admite claves externas ...

http://www.sqlite.org/foreignkeys.html "Este documento describe el soporte para las restricciones de clave externa SQL introducidas en SQLite versión 3.6.19."

En Froyo es la versión de SQLite 3.6.22, entonces ...

EDITAR: para ver la versión de sqlite: adb shell sqlite3 -version


Las claves foráneas con "on delete cascade" son compatibles con SQLite en Android 2.2 y versiones posteriores. Pero tenga cuidado al usarlos: algunas veces se informa un error al activar una clave externa en una columna, pero el problema real reside en otra restricción de clave externa de otra columna en la tabla secundaria o en alguna otra tabla que haga referencia a esta tabla.

Parece que SQLite verifica todas las restricciones cuando enciende uno de ellos. En realidad se menciona en la documentación. Controles de restricción DDL frente a DML.


Las restricciones de clave externa con cascada de eliminación son compatibles, pero debe habilitarlas.
Acabo de agregar lo siguiente a mi SQLOpenHelper , que parece ser el truco.

@Override public void onOpen(SQLiteDatabase db) { super.onOpen(db); if (!db.isReadOnly()) { // Enable foreign key constraints db.execSQL("PRAGMA foreign_keys=ON;"); } }

Decidí mi columna de referencia de la siguiente manera.

mailbox_id INTEGER REFERENCES mailboxes ON DELETE CASCADE


Lo que sea que @phil mencionó es bueno. Pero puede usar otro método predeterminado disponible en la Base de datos para establecer la clave externa. Eso es setForeignKeyConstraintsEnabled (true).

@Override public void onOpen(SQLiteDatabase db) { super.onOpen(db); if (!db.isReadOnly()) { // Enable foreign key constraints db.execSQL("PRAGMA foreign_keys=ON;"); //(OR) db.setForeignKeyConstraintsEnabled (true) } }

Para documentos, consulte SQLiteDatabase.setForeignKeyConstraintsEnabled


No creo que SQLite apoye esto de manera inmediata. Lo que estoy haciendo en mis aplicaciones es:

  1. Crear transacción
  2. Eliminar datos detallados (puntos intermedios en su ejemplo)
  3. Eliminar datos maestros (pistas en su ejemplo)
  4. Commitir la transacción en el éxito

De esa forma, estoy seguro de que se borraron todos los datos o ninguno.


Nunca es demasiado viejo de una pregunta para responder con una respuesta más completa.

@Override public void onOpen(SQLiteDatabase db) { super.onOpen(db); if (!db.isReadOnly()) { setForeignKeyConstraintsEnabled(db); } mOpenHelperCallbacks.onOpen(mContext, db); } private void setForeignKeyConstraintsEnabled(SQLiteDatabase db) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { setForeignKeyConstraintsEnabledPreJellyBean(db); } else { setForeignKeyConstraintsEnabledPostJellyBean(db); } } private void setForeignKeyConstraintsEnabledPreJellyBean(SQLiteDatabase db) { db.execSQL("PRAGMA foreign_keys=ON;"); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void setForeignKeyConstraintsEnabledPostJellyBean(SQLiteDatabase db) { db.setForeignKeyConstraintsEnabled(true); }


Triggers son compatibles con Android y ese tipo de eliminación en cascada no es compatible con sqlite. Un ejemplo del uso de desencadenadores en Android se puede encontrar here . Aunque usar transacciones como declaró Thorsten probablemente sea tan fácil como un disparador.