2011-08-04 21 views
16

Estoy tratando de configurar una base de datos SQLite3 con foo sy bar sy una relación muchos a muchos entre ellos. Esto es lo que tengo hasta ahora:relación muchos-a-muchos SQLite?

CREATE TABLE foo(
    id INTEGER PRIMARY KEY NOT NULL, 
    foo_col INTEGER NOT NULL 
); 
CREATE TABLE bar(
    id INTEGER PRIMARY KEY NOT NULL, 
    bar_col TEXT NOT NULL 
); 
CREATE TABLE foobar(
    foo_id INTEGER, 
    bar_id INTEGER, 
    FOREIGN KEY(foo_id) REFERENCES foo(id) ON DELETE CASCADE, 
    FOREIGN KEY(bar_id) REFERENCES bar(id) ON DELETE CASCADE 
); 
CREATE INDEX fooindex ON foobar(foo_id); 
CREATE INDEX tagindex ON foobar(tag_id); 

... pero parece que no funciona. Puedo eliminar una fila de foo y no afecta a foobar. ¿Qué estoy haciendo mal?

Respuesta

13

Tomado de este sitio, http://www.sqlite.org/foreignkeys.html.

Suponiendo que la biblioteca está compilada con restricciones de clave foránea habilitadas, la aplicación aún debe habilitarla en el tiempo de ejecución, utilizando el comando PRAGMA foreign_keys. Por ejemplo:

sqlite> PRAGMA foreign_keys = ON; 

restricciones de clave externa están desactivados por defecto (para la compatibilidad hacia atrás), por lo que deben estar habilitadas por separado para cada conexión de base de datos por separado. (Sin embargo, tenga en cuenta que las versiones futuras de SQLite pueden cambiar de modo que las restricciones de clave externa se habiliten de manera predeterminada. Los desarrolladores cuidadosos no harán suposiciones sobre si las claves externas están habilitadas o no por defecto, sino que las habilitará o deshabilitará según sea necesario). la aplicación también puede usar una instrucción PRAGMA foreign_keys para determinar si las claves externas están actualmente habilitadas. La siguiente sesión de línea de comandos demuestra esto:

sqlite> PRAGMA foreign_keys; 
0 
sqlite> PRAGMA foreign_keys = ON; 
sqlite> PRAGMA foreign_keys; 
1 
sqlite> PRAGMA foreign_keys = OFF; 
sqlite> PRAGMA foreign_keys; 
0 

Consejo: Si el comando "FOREIGN_KEYS PRAGMA" no devuelve datos en lugar de una sola fila que contiene "0" o "1", entonces la versión de SQLite está utilizando no admite claves externas (ya sea porque es anterior a 3.6.19 o porque se compiló con SQLITE_OMIT_FOREIGN_KEY o SQLITE_OMIT_TRIGGER definido).

No se pueden habilitar o deshabilitar las restricciones de clave externa en el medio de una transacción de varias instrucciones (cuando SQLite no está en modo de confirmación automática). Intentar hacerlo no devuelve un error; simplemente no tiene ningún efecto.

+0

La tabla foobar también probablemente necesita una restricción de clave primaria en (foo_id, bar_id). Pero ese es un problema diferente. –

+0

@Catcall: Siéntase libre de comentar sobre mi publicación. – wes

+0

La respuesta de ace, que proviene directamente de la documentación de SQLite, es precisa y completa. Pero como dije, la tabla foobar también necesita 'PRIMARY KEY (foo_id, bar_id)'. –