Saya memiliki dua tabel: trek dan titik arah, sebuah trek dapat memiliki banyak titik lewat, tetapi titik jalan ditetapkan hanya untuk 1 trek.
Dalam tabel poin cara saya memiliki kolom bernama "trackidfk" yang menyisipkan track_ID setelah trek dibuat, namun saya belum menyiapkan batasan Kunci Asing pada kolom ini.
Saat saya menghapus lintasan, saya ingin menghapus titik lewat yang telah ditetapkan, apakah ini mungkin ?. Saya membaca tentang menggunakan Pemicu tetapi saya rasa mereka tidak didukung di Android.
Untuk membuat tabel titik jalan:
public void onCreate(SQLiteDatabase db) {
db.execSQL( "CREATE TABLE " + TABLE_NAME
+ " ("
+ _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ LONGITUDE + " INTEGER,"
+ LATITUDE + " INTEGER,"
+ TIME + " INTEGER,"
+ TRACK_ID_FK + " INTEGER"
+ " );"
);
...
}
sumber
PRAGMA
pernyataanonConfigure()
tetapi itu membutuhkan API level 16 (Android 4.1), dan saat itu Anda cukup meneleponsetForeignKeyConstraintsEnabled
.onCreate
/onDowngrade
/onUpgrade
, yang sebelumnyaonOpen
. Lihat kode sumber di Android 4.1.1 .Sejak Android 4.1 (API 16) SQLiteDatabase mendukung:
public void setForeignKeyConstraintsEnabled (boolean enable)
sumber
Seperti yang dikatakan oleh posting dari e.shishkin dari API 16 ke atas, Anda harus mengaktifkan batasan kunci asing dalam
SqLiteOpenHelper.onConfigure(SqLiteDatabase)
metode menggunakandb.setForeignKeyConstraintsEnabled(boolean)
@Override public void onConfigure(SQLiteDatabase db){ db.setForeignKeyConstraintsEnabled(true); }
sumber
Tidak pernah ada pertanyaan yang terlalu tua untuk dijawab dengan jawaban yang lebih lengkap.
@Override public void onOpen(SQLiteDatabase db) { super.onOpen(db); if (!db.isReadOnly()) { setForeignKeyConstraintsEnabled(db); } mOpenHelperCallbacks.onOpen(mContext, db); } private void setForeignKeyConstraintsEnabled(SQLiteDatabase db) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { setForeignKeyConstraintsEnabledPreJellyBean(db); } else { setForeignKeyConstraintsEnabledPostJellyBean(db); } } private void setForeignKeyConstraintsEnabledPreJellyBean(SQLiteDatabase db) { db.execSQL("PRAGMA foreign_keys=ON;"); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void setForeignKeyConstraintsEnabledPostJellyBean(SQLiteDatabase db) { db.setForeignKeyConstraintsEnabled(true); }
sumber
Apapun @phil yang disebutkan itu bagus. Tetapi Anda dapat menggunakan metode default lain yang tersedia di Database itu sendiri untuk menyetel kunci asing. Yaitu setForeignKeyConstraintsEnabled (true).
@Override public void onOpen(SQLiteDatabase db) { super.onOpen(db); if (!db.isReadOnly()) { // Enable foreign key constraints db.execSQL("PRAGMA foreign_keys=ON;"); //(OR) db.setForeignKeyConstraintsEnabled (true) } }
Untuk Dokumen, lihat SQLiteDatabase.setForeignKeyConstraintsEnabled
sumber
A good time to call this method is right after calling openOrCreateDatabase(File, SQLiteDatabase.CursorFactory) or in the onConfigure(SQLiteDatabase) callback.
Jadi, alih-alihonOpen
,onConfigure
tampaknya tempat yang tepat.Saya tidak berpikir SQLite mendukung ini di luar kotak. Apa yang saya lakukan di aplikasi saya adalah:
Dengan cara itu saya yakin bahwa semua data akan dihapus atau tidak ada.
sumber
Pemicu didukung oleh android dan jenis penghapusan kaskade tersebut tidak didukung oleh sqlite. Contoh penggunaan pemicu di android dapat ditemukan di sini . Meskipun menggunakan transaksi seperti yang dinyatakan Thorsten mungkin semudah pemicu.
sumber
Versi SQLite di android 1.6 adalah 3.5.9 sehingga tidak mendukung kunci asing ...
http://www.sqlite.org/foreignkeys.html "Dokumen ini menjelaskan dukungan untuk kendala kunci asing SQL yang diperkenalkan di SQLite versi 3.6.19."
Di Froyo itu SQLite versi 3.6.22, jadi ...
EDIT: untuk melihat versi sqlite: adb shell sqlite3 -version
sumber
Kunci asing dengan "on delete cascade" didukung di SQLite di Android 2.2 dan lebih tinggi. Namun berhati-hatilah saat menggunakannya: terkadang kesalahan dilaporkan saat mengaktifkan satu kunci asing pada satu kolom, tetapi masalah sebenarnya terletak pada batasan kunci asing kolom lain di tabel anak, atau tabel lain yang mereferensikan tabel ini.
Sepertinya SQLite memeriksa semua batasan saat mengaktifkan salah satunya. Itu sebenarnya disebutkan dalam dokumentasi. Pemeriksaan kendala DDL versus DML.
sumber
Jika Anda menggunakan Android Room, lakukan seperti yang ditunjukkan di bawah ini.
Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME) .addCallback(object : RoomDatabase.Callback() { // Called when the database has been opened. override fun onOpen(db: SupportSQLiteDatabase) { super.onOpen(db) //True to enable foreign key constraints db.setForeignKeyConstraintsEnabled(true) } // Called when the database is created for the first time. override fun onCreate(db: SupportSQLiteDatabase) { super.onCreate(db) } }).build()
sumber