Mal funcionamiento al eliminar de la tabla de base de datos Sqlite (comportamiento extraordinario de relación)

Tengo un extraño problema en mi aplicación Android que está relacionado con las relaciones de base de datos en claves foráneas. Los siguientes códigos describen la estructura de mi base de datos simple, he utilizado SQLiteOpenHelper como una superclase para manejar la operación de la base de datos

private static final String CATEGORIES_TABLE = "CREATE TABLE __CATEGORIES_TBL(_id INTEGER PRIMARY KEY AUTOINCREMENT, _name TEXT NOT NULL, _desc TEXT NULL," + "_create_date INTEGER NOT NULL, _update_date INTEGER NULL" + ", _parent_id INTEGER NULL, FOREIGN KEY(_parent_id) REFERENCES __CATEGORIES_TBL(_id) ON DELETE RESTRICT);"; private static final String CARDS_TABLE = "CREATE TABLE __CARDS_TBL(_id INTEGER PRIMARY KEY AUTOINCREMENT," + "_value TEXT NOT NULL, _play_count INTEGER NULL, " + "_category_id INTEGER NOT NULL, FOREIGN KEY(_category_id) REFERENCES __CATEGORIES_TBL(_id) ON DELETE RESTRICT);"; @Override public void onCreate(SQLiteDatabase db) { try { db.execSQL("PRAGMA foreign_keys = ON;"); db.execSQL(CATEGORIES_TABLE); db.execSQL(CARDS_TABLE); Logger.i("DB-INIT-DONE!"); } catch (Exception ex) { Logger.e("Database on create error", ex); } } 

como ves todo parece estar bien y lo es; Puedo insertar, corregir, seleccionar la fila a / de ambas tablas pero desafortunadamente puedo suprimir filas que tienen filas del niño. como yo esperaba. porque establecí la relación FK (foreign-key) entre las tablas de remolque con el modo ON DELETE RESTRICT por lo tanto espero obtener una excepción cuando intento eliminar una fila de la tabla principal (__CATEGORIES_TBL), en realidad el registro principal está borrando y ninguna excepción sucede

por teoría sqlite debe evitar borrar cualquier fila en __CATEGORIES_TBL cuando tiene una o más filas hijo en __CARDS_TBL o cualquier fila hijo en __CATEGORIES_TBL pero en mi aplicación puedo eliminar filas cuando tiene una fila de relaciones padre-hijo,

considere el siguiente código (este es el código de supresión)

 private SQLiteDatabase db; public long delete(long objId) { try { // TABLE_NAME can be __CATEGORIES_TBL or __CARDS_TBL based on program flow return db.delete(TABLE_NAME, COLUMN_ROWID + "=" + objId, null); } catch (Exception e) { Logger.d("Unable to delete category <" + objId + ">.", e); return -123456; } } 

cada llamada a db.delete devuelve 1 (significa que 1 fila es borrada por este comando) este código se ejecuta en android 2.3;

Gracias por adelantado.

Recibo el comportamiento que esperaría de SQLite 3.7.9.

 sqlite> CREATE TABLE __CATEGORIES_TBL ( ...> _id INTEGER PRIMARY KEY AUTOINCREMENT, ...> _name TEXT NOT NULL, ...> _desc TEXT NULL, ...> _create_date INTEGER NOT NULL, ...> _update_date INTEGER NULL, ...> _parent_id INTEGER NULL, ...> FOREIGN KEY(_parent_id) ...> REFERENCES __CATEGORIES_TBL(_id) ON DELETE RESTRICT ...> ); sqlite> sqlite> CREATE TABLE __CARDS_TBL( ...> _id INTEGER PRIMARY KEY AUTOINCREMENT, ...> _value TEXT NOT NULL, ...> _play_count INTEGER NULL, ...> _category_id INTEGER NOT NULL, ...> FOREIGN KEY(_category_id) ...> REFERENCES __CATEGORIES_TBL(_id) ON DELETE RESTRICT ...> ); sqlite> sqlite> insert into __categories_tbl values ...> (1, 'name', 'desc',current_date,current_date,1); sqlite> insert into __cards_tbl values (1, 'value',3, 1); sqlite> pragma foreign_keys=on; sqlite> select * from __categories_tbl; 1|name|desc|2012-08-25|2012-08-25|1 sqlite> delete from __categories_tbl; Error: foreign key constraint failed 

Si yo fuera usted, intentaría inspeccionar visualmente la base de datos de SQLite después de cada paso para ver si lo que usted espera que suceda realmente está sucediendo. IIRC, no todos los fallos plantearán una excepción.


El soporte de claves externas se introdujo en la versión 3.6.19. Hay configuraciones de tiempo de compilación que permiten a SQLite analizar las restricciones de clave externa, pero no permiten que las realice. (SQLITE_OMIT_TRIGGER definido, SQLITE_OMIT_FOREIGN_KEY no definido.) Debería ser capaz de decir si su compilación de SQLite puede hacer cumplir claves foráneas intentando crear un desencadenador.

Si la creación de un desencadenador falla con un error de análisis, SQLite analizará las sentencias de clave externa, pero no las aplicará. Tendrá que volver a compilar su versión de 3.6.19, o actualizar a una versión más reciente. (Y compruebe esas configuraciones antes de compilar.)

Una columna declarada NOT NULL puede parecer vacía si ha insertado una cadena vacía. De forma predeterminada, las cadenas NULL y vacías parecen idénticas en la salida. Puede saber si una columna contiene valores nulos seleccionándolos.

 select * from table_name where column_name is null; 

sobre este problema he puesto un db.execSQL ("pragma foreign_keys = on;"); antes de eliminar la sentencia en mi código de aplicación, a continuación, el problema resuelto, pero creo que este es un código innecesario, quizás instalados mi teléfono sqlite configs están mal y necesita ser reconfigurado, es posible reconfigurar el sqlite en el teléfono? el dispositivo de prueba es un incendio silvestre HTC s (versión sqlite corriendo es 3.7.2)

  • SQLite - No se pudo abrir el archivo de base de datos
  • SQLiteException no se captura
  • SQLITE - eliminar filas con join interno?
  • La base de datos SQLite no funciona en Android 4.4
  • Cómo contar el número de registros en sqlite en Android
  • Utilización de la base de datos legible y escrita de SQLite
  • SQLiteDatabase actualización no funciona?
  • Tener varios SQLiteOpenhelper en una aplicación Android
  • ¿Cómo establecer el tipo de datos en SQLiteDatabase vinculación de consulta en bruto?
  • Cómo superar el límite de 65535 bytes para el código de método
  • Actividad y acceso al fondo de acceso a la base de datos SQLite
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.