Я создал две таблицы под названием TermTable и CourseTable. Я хочу, чтобы у CourseTable был внешний ключ для ссылки на TermTable.
Это код, в котором я создаю таблицы:
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TermDbSchema.TermTable.NAME + "(" +
"_id integer primary key autoincrement, " +
TermDbSchema.TermTable.Cols.UUID + ", " +
TermDbSchema.TermTable.Cols.TITLE + ", " +
TermDbSchema.TermTable.Cols.START_DATE + ", " +
TermDbSchema.TermTable.Cols.END_DATE +
")"
);
//I want to give CourseTable a foreign key to reference TermTable^^
db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
"_id integer primary key autoincrement, " +
TermDbSchema.CourseTable.Cols.UUID + ", " +
TermDbSchema.CourseTable.Cols.TITLE + ", " +
TermDbSchema.CourseTable.Cols.START_DATE + ", " +
TermDbSchema.CourseTable.Cols.END_DATE + ", " +
TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_EMAIL +
")"
);
}
Это код схемы кода:
public class TermDbSchema {
public static final class TermTable {
public static final String NAME = "terms";
public static final class Cols {
public static final String UUID = "uuid";
public static final String TITLE = "title";
public static final String START_DATE = "startdate";
public static final String END_DATE = "enddate";
}
}
public static final class CourseTable {
public static final String NAME = "courses";
public static final class Cols {
public static final String UUID = "uuid";
public static final String TITLE = "title";
public static final String START_DATE = "startdate";
public static final String END_DATE = "enddate";
public static final String COURSE_STATUS = "coursestatus";
public static final String OPTIONAL_NOTE = "optionalnote";
public static final String MENTOR_NAME = "mentorname";
public static final String MENTOR_PHONE = "mentorphone";
public static final String MENTOR_EMAIL = "mentoremail";
}
}
Как добавить внешний ключ в CourseTable, чтобы он мог ссылаться на TermTable?
Также описано с примерами здесь: sqlite.org/foreignkeys.html




Определите строку внутри класса Cols класса CourseTable, которая будет содержать имя этого нового столбца, например:
public static final String TERM_ID = "term_id";
Измените CREATE оператор таблицы CourseTable:
db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
"_id integer primary key autoincrement, " +
TermDbSchema.CourseTable.Cols.UUID + ", " +
TermDbSchema.CourseTable.Cols.TITLE + ", " +
TermDbSchema.CourseTable.Cols.START_DATE + ", " +
TermDbSchema.CourseTable.Cols.END_DATE + ", " +
TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_EMAIL + ", " +
TermDbSchema.CourseTable.Cols.TERM_ID + " INTEGER, " +
"FOREIGN KEY (" + TermDbSchema.CourseTable.Cols.TERM_ID +
") REFERENCES " + TermDbSchema.TermTable.NAME + "(_id)" +
")"
);
Этот новый столбец будет ссылаться на столбец _id, который является ПЕРВИЧНЫМ КЛЮЧЕМ TermTable.
Вам нужно удалить приложение с устройства, чтобы база данных была удалена, а затем повторно запустить, чтобы воссоздать базу данных.
это нехорошо setForeignKeyConstraintsEnabled(true) для открытия базы данных или onConfigure, в противном случае ничего не происходит.
Измените CourseTable, чтобы иметь другой столбец для ссылки (ссылка, отношение, ассоциация, сопоставление — все остальные термины): -
public static final class CourseTable {
public static final String NAME = "courses";
public static final class Cols {
public static final String UUID = "uuid";
public static final String TITLE = "title";
public static final String START_DATE = "startdate";
public static final String END_DATE = "enddate";
public static final String COURSE_STATUS = "coursestatus";
public static final String OPTIONAL_NOTE = "optionalnote";
public static final String MENTOR_NAME = "mentorname";
public static final String MENTOR_PHONE = "mentorphone";
public static final String MENTOR_EMAIL = "mentoremail";
public static final String TERM_LINK = "termlink" //<<<<<<<<<< ADDED
}
Измените таблицу Создание SQL для курсов, чтобы добавить ограничение внешнего ключа.
db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
"_id integer primary key autoincrement, " +
TermDbSchema.CourseTable.Cols.UUID + ", " +
TermDbSchema.CourseTable.Cols.TITLE + ", " +
TermDbSchema.CourseTable.Cols.START_DATE + ", " +
TermDbSchema.CourseTable.Cols.END_DATE + ", " +
TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_EMAIL + ", " + //<<<<<<<<<< CHANGED
TermDbSchema.CourseTable.Cols.TERM_LINK + " INTEGER REFERENCES " + TermDbSchema.TermTable.NAME + "(_id)" + //<<<<<<<<<< ADDED
")"
);
Затем переопределите onConfigure, чтобы вызвать передачу setForeignKeyConstraintsEnabled true.
например :-
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
Затем вам нужно будет сделать 1 из следующего: -
а затем перезапустите приложение.
Обратите внимание, что определение внешнего ключа ТОЛЬКО определяет ограничение (правило), которое требует, чтобы значение помещалось в столбец, который имеет ограничение, чтобы быть значением в одной из строк родительской таблицы/столбца, на который ссылаются.
Определение ограничения внешнего ключа НЕ ОБЕСПЕЧИВАЕТ автоматические установление отношений. То есть вам все равно придется определять соответствующий термин при добавлении курса (распространенное заблуждение состоит в том, что он это делает).
Возможно, вы захотите расширить определение, включив в него действия ON DELETE и ON UPDATE, такие как CASCADE. например ON DELETE CASCADE при удалении строки термина (если) удаляет дочерние строки в таблице курса. Точно так же ON UPDATE CASCADE обновит ссылочное значение дочерних элементов в таблице курсов, если это значение будет изменено в таблице терминов (это может упростить жизнь).
например вы можете использовать: -
TermDbSchema.CourseTable.Cols.TERM_LINK + " INTEGER REFERENCES " + TermDbSchema.TermTable.NAME + "(_id) ON DELETE CASCADE ON UPDATE CASCADE" + //<<<<<<<<<< ADDED
Вы можете обратиться к Поддержка внешнего ключа SQLite
Посмотрите синтаксис
CREATE TABLE, в том числе, как пометить столбцы как внешние ключи, здесь: sqlite.org/lang_createtable.html