SQLite ошибка Android: несоответствие внешнего ключа при вставке в базу данных - PullRequest
0 голосов
/ 30 марта 2012

и заранее спасибо! Я схожу с ума от ошибки, когда пытаюсь вставить в таблицу, которая имеет внешние ключи. Значения существуют, относятся к одному типу и не равны нулю ... И тем более забавно, что первый раз терпит неудачу, и только первый! Другие вставки работают отлично! Я попытался удалить вставку и повторить, и ошибка не выдается снова ... Только в первый раз! Я пробую это на Android 2.2 (Froyo), а до этого был в 2.1 без внешних ключей.

Извините за большое "сообщение", но я потерялся!

ошибка:


03-30 16:59:56.333: E/AndroidRuntime(28007): android.database.sqlite.SQLiteException: foreign key mismatch: , while compiling: INSERT INTO productoslista(idProducto, idUnidad, comprado, idLista, comentario, cantidad) VALUES(?, ?, ?, ?, ?, ?);
03-30 16:59:56.333: E/AndroidRuntime(28007):    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
03-30 16:59:56.333: E/AndroidRuntime(28007):    at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
03-30 16:59:56.333: E/AndroidRuntime(28007):    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
03-30 16:59:56.333: E/AndroidRuntime(28007):    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
03-30 16:59:56.333: E/AndroidRuntime(28007):    at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:36)
03-30 16:59:56.333: E/AndroidRuntime(28007):    at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1145)
03-30 16:59:56.333: E/AndroidRuntime(28007):    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1536)
03-30 16:59:56.333: E/AndroidRuntime(28007):    at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1432)

таблица:


CREATE TABLE [ProductosLista] (
[idLista] INTEGER  NOT NULL,
[idProducto] INTEGER  NOT NULL,
[cantidad] INTEGER  NOT NULL,
[idUnidad] INTEGER  NOT NULL,
[comprado] INTEGER  NOT NULL,
[comentario] TEXT,
PRIMARY KEY ([idLista],[idProducto],[comentario]),
FOREIGN KEY (idLista) REFERENCES Listas(idLista),
FOREIGN KEY (idProducto) REFERENCES Productos(idProducto),
FOREIGN KEY (idUnidad) REFERENCES Unidades(idUnidad)



CREATE TABLE [Listas] (
[idLista] INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL,
[descripcion] TEXT  UNIQUE NOT NULL,
[fechaCreacion] INTEGER  NOT NULL,
[visible] TEXT  NOT NULL,
[estadoCompra] INTEGER NOT NULL
);

CREATE TABLE [Unidades] (
[idUnidad] INTEGER  NOT NULL,
[idIdioma] INTEGER  NOT NULL,
[abreviatura] TEXT  NOT NULL,
[descripcion] TEXT  NOT NULL,
--PRIMARY KEY ([idUnidad],[idIdioma]),
FOREIGN KEY (idIdioma) REFERENCES Idiomas(idIdioma)
);

CREATE TABLE [Productos] (
[idProducto] INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL,
[idPadre] INTEGER  NOT NULL,
[idCategoria] INTEGER  NOT NULL,
[idTipoAlimentacion] INTEGER NOT NULL,
[eliminado] INTEGER NOT NULL,
[imagen] INTEGER,
FOREIGN KEY (idPadre) REFERENCES Productos(idProducto),
FOREIGN KEY (idCategoria) REFERENCES Categorias(idCategoria)
);

Ответы [ 2 ]

1 голос
/ 21 июня 2012

и извините за опоздание. Я решил эту проблему, изменив таблицу "unidades", чтобы иметь один первичный ключ, а не один составной. Таким образом, ошибка вставки в «productoslista» произошла из-за того, что внешний ключ из «productoslista» ссылался на часть составного PK таблицы «unidades»

Проблема заключалась в том, что sqlite не нравится, когда вы ссылаетесь на одно поле из составного первичного ключа, поэтому решение состоит в том, чтобы иметь единственные первичные ключи и избегать составных.

Этот последний тип PK является причиной плохого дизайна (я много читал об этом), поэтому лучше перепроектировать таблицы, чтобы иметь одиночные PK, и не проблема создать больше таблиц, если дизайн будет более гибким и читаемый. Кстати, спасибо всем!

1 голос
/ 13 июня 2012

Вы должны удалить свою базу данных и снова запустить приложение. Вы удалите свою базу данных с открытым эмулятором, затем откроете вкладку файлового проводника и перейдите в папку, где находится банк. Извините за английские ошибки. Я бразилец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...