Mam dwie tabele: ścieżki i punkty trasy, ścieżka może mieć wiele punktów, ale punkt drogi jest przypisany tylko do jednej ścieżki.
W tabeli punktów sposób mam kolumnę o nazwie "trackidfk", która wstawia track_ID po utworzeniu ścieżki, jednak nie ustawiłem ograniczeń klucza obcego w tej kolumnie.
Kiedy usuwam ślad Chcę usunąć przypisane punkty, czy jest to możliwe? Czytałem o używaniu wyzwalaczy, ale nie sądzę, aby były obsługiwane w systemie Android.
Aby utworzyć tabelę punktów trasy:
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"
+ " );"
);
...
}
java
android
sqlite
foreign-keys
jcrowson
źródło
źródło
PRAGMA
oświadczeń w,onConfigure()
ale wymaga to poziomu API 16 (Android 4.1), a wtedy możesz po prostu wywołaćsetForeignKeyConstraintsEnabled
.onCreate
/onDowngrade
/onUpgrade
, które są wcześniejonOpen
. Zobacz kod źródłowy w systemie Android 4.1.1 .Od Androida 4.1 (API 16) SQLiteDatabase obsługuje:
public void setForeignKeyConstraintsEnabled (boolean enable)
źródło
Jak mówi post z e.shishkin od API 16 w górę, powinieneś włączyć ograniczenia klucza obcego w
SqLiteOpenHelper.onConfigure(SqLiteDatabase)
metodzie używającejdb.setForeignKeyConstraintsEnabled(boolean)
@Override public void onConfigure(SQLiteDatabase db){ db.setForeignKeyConstraintsEnabled(true); }
źródło
Nigdy nie jest zbyt stare pytanie, by udzielić pełniejszej odpowiedzi.
@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); }
źródło
Wszystko, o czym wspomniał @phil, jest dobre. Ale możesz użyć innej domyślnej metody dostępnej w samej bazie danych, aby ustawić klucz obcy. To jest 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) } }
W przypadku dokumentów odwołaj się do SQLiteDatabase.setForeignKeyConstraintsEnabled
źródło
A good time to call this method is right after calling openOrCreateDatabase(File, SQLiteDatabase.CursorFactory) or in the onConfigure(SQLiteDatabase) callback.
Więc zamiastonOpen
,onConfigure
wydaje się, że to właściwe miejsce.Nie sądzę, aby SQLite obsługiwał to po wyjęciu z pudełka. W moich aplikacjach robię:
W ten sposób mam pewność, że wszystkie dane zostaną usunięte lub żadne.
źródło
Wyzwalacze są obsługiwane przez system Android, a ten typ usuwania kaskadowego nie jest obsługiwany przez sqlite. Przykład użycia wyzwalaczy na Androidzie można znaleźć tutaj . Chociaż używanie transakcji, jak stwierdził Thorsten, jest prawdopodobnie tak samo łatwe jak wyzwalanie.
źródło
Wersja SQLite w systemie Android 1.6 to 3.5.9, więc nie obsługuje kluczy obcych ...
http://www.sqlite.org/foreignkeys.html „Ten dokument opisuje obsługę ograniczeń klucza obcego SQL wprowadzonych w SQLite 3.6.19.”
We Froyo jest to SQLite w wersji 3.6.22, więc ...
EDYCJA: aby zobaczyć wersję sqlite: adb shell sqlite3 -version
źródło
Klucze obce z kaskadą „przy usuwaniu” są obsługiwane w SQLite w systemie Android 2.2 i nowszych. Ale bądź ostrożny podczas ich używania: czasami zgłaszany jest błąd podczas odpalania jednego klucza obcego w jednej kolumnie, ale prawdziwy problem leży w ograniczeniu klucza obcego innej kolumny w tabeli potomnej lub w innej tabeli, która odwołuje się do tej tabeli.
Wygląda na to, że SQLite sprawdza wszystkie ograniczenia podczas uruchamiania jednego z nich. Faktycznie jest to wymienione w dokumentacji. Sprawdzanie ograniczeń DDL i DML.
źródło
Jeśli korzystasz z Android Room, wykonaj poniższe czynności.
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()
źródło