2012-02-29 2 views
2

Я разрабатываю приложение Android 2.2+ с поддержкой SQLite db. Я пытаюсь определить ограничения ссылочной целостности при создании таблиц. Я также включил поддержку внешнего ключа, выполнив db.execSQL("PRAGMA foreign_keys=ON;"); в onCreate и onOpen методах SQLiteOpenHelper. Afteer, настраивая мои таблицы и соответствующие ссылки на внешние ключи, по-прежнему позволяет мне insert строк в таблицах, где отсутствуют контрольные записи. Напр. Я следующая структуруAndroid 2.2 + SQLite + Определение ограничений ссылочной целостности

CREATE TABLE Questions(_id integer primary key,question text not null); 
CREATE TABLE Ques_Ans(_id integer primary key autoincrement,qid integer not null, 
         aid integer not null,is_correct integer default 0, 
         FOREIGN KEY (qid) REFERENCES Questions(_id)); 

и после моих данных в таблице

INSERT INTO Questions VALUES(1, 'Some text'); 
INSERT INTO Ques_Ans(qid, aid, is_correct) VALUES(20, 1, 0); 

Если внешний ключ правильно установлен на столе Ques_Ans, вторая вставка должна провалилась, поскольку нет никаких записей в Questions таблицы с id 20, но почему-то мое приложение не выбрасывает какую-либо ошибку и вставляет второй оператор insert. Может кто-нибудь сказать мне, что здесь не так, или я не вижу никакой конфигурации здесь?

Update [03-Mar-2012]: После обсуждения нити с @Catcall

  • Использование sqlite3 инструмента, переключение на PRAGMA foreign_keys=ON; иностранных ключевых работ, как ожидается
  • То же самое, если использовать через приложение на эмуляторе или на Телефон не работает
  • Вставьте операторы, выполненные с использованием insert() или execSQL(). Ни один из них не выбрасывает foreign key constraint failed error
  • PRAGMA integrity_checkok. Таким образом, база данных не повреждена.
+0

+1 только для того, чтобы включить весь SQL, который может возникнуть, чтобы воспроизвести проблему. –

+0

просто примечание для будущих читателей. То же самое существует и с 2015 года. –

ответ

1

Ваш внешний ключ находится в столбце «qid», а не в столбце «_id».

Это INSERT заявление

INSERT INTO Ques_Ans VALUES(20, 1, 0); 

должен кинули ошибку

Error: table Ques_Ans has 4 columns but 3 values were supplied 

Этот ВСТАВИТЬ должен преуспеть.

INSERT INTO Ques_Ans VALUES(20, 1, 0, 0); 

Этот человек должен потерпеть неудачу.

INSERT INTO Ques_Ans VALUES(21, 2, 0, 0); 
Error: foreign key constraint failed 

Позже. , ,

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

Это идиома для транзакций базы данных.

db.beginTransaction(); 
    try { 
    ... 
    db.setTransactionSuccessful(); 
    } finally { 
    db.endTransaction(); 
    } 

Android документы предлагают использовать insert() вместо execSQL(). Убедитесь, что вы ловушки, ловушки или проверки ошибок в каждой функции, которая может вернуть ошибку. Так, например, если вы переключитесь на insert(), проверьте его возвращаемое значение на -1.

Если это не поможет, вы можете попробовать пометить этот вопрос с помощью «Java» (например) или задать новый вопрос, который фокусируется на вашем коде и на ошибках ловушки.

+0

Спасибо @Catcall. Первоначально я набрал неверный запрос Insert. Я скорректировал его, отредактировав исходный вопрос. – Jay

+0

Чтобы быть ясным, проблема ссылочной целостности все еще существует. Изменение запроса было только для сообщения, мой фактический код имеет скрипт вставки, как я исправил в вопросе. Так что по достоинству оцените любую помощь в этом вопросе. – Jay

+0

@Jay: Ваш отредактированный запрос не работает здесь: «Ошибка: ограничение внешнего ключа не удалась». Попробуйте запустить PRAGMA integrity_check; ', чтобы узнать, повреждена ли ваша база данных. –

0

В SQLite Ограничения внешнего ключа по умолчанию отключены (для обратной совместимости). Вы должны включить его с помощью

PRAGMA foreign_keys = 1 после установления соединения с базой данных. Вот ссылка на официальные документы, которые объясняют это более подробно. http://sqlite.org/foreignkeys.html Пожалуйста, перейдите к включению поддержки внешнего ключа в приведенной выше ссылке.

Смежные вопросы