2012-03-05 10 views
1

私はすべての3つのテーブルから行を削除する必要があり、非常に単純なリンクテーブルを設定しているAndroid搭載SQLiteでリンク行を削除するにはどうすればよいですか?

表1 - 割り付け{assignment_id}

LinkTable - AssignmentTasks {assignment_id、TASK_ID}

表2 - タスク{task_id}

私はIDを持っているので、割り当てと割り当てのタスクから簡単に削除できますが、この割り当てに関連するタスクのリストはありません。

私は割り当てに関連するすべてのtask_idsを返すカーソルを構築しましたが、リンクテーブル内のレコードは、それらを参照しながら、私はそれらを削除することはできません。 (私は外部キー制約が他の場所で参照されている行を削除するのを止めなければならないと思います)

私はtask_idsのリストを保存し、assignment_tasksレコードを削除し、割り当てレコードを削除してからストアリストを反復する必要がありますtask_idsを削除して各タスクを削除しますか?またはこれを行うためのより良い方法がありますか?

答えて

1

それとも、一時的にオフにチェックする外部キー制約を変えることができますが:

pragma foreign_keys = off; 

しかし、それは必要ありません。

他の問題は、現在、多対多の関係として記述されていることです。これは、複数の割り当てが1つのタスクを参照できることを意味する。それを参照している課題の1つが削除されただけなので、タスクを削除するのは問題ではないでしょう。代わりに、削除する前にタスクが参照されていないことを確認する必要があります。

あなたが本当に唯一の割り当てに所属する各タスクのためのものならば別の方法として、あなたはこのようなあなたのスキーマを設定できます。

CREATE TABLE Assignment (assignment_id int PRIMARY KEY); 
CREATE TABLE Task (
    task_id int PRIMARY KEY, 
    assignment_id int FOREIGN KEY REFERENCES Assignment ON DELETE CASCADE 
); 

ON DELETE CASCADEビットは、タスクエントリがいる場合には削除されますそれが参照する割り当ては削除されます。もちろん、外部キー制約が有効な場合にのみ機能します。代入がトリガーによって削除されている場合や、他のカスケードのために割り当てられている場合は、pragma recursive_triggers = onで再帰トリガーも有効にする必要があります。

別の可能性(元のスキーマを保持したい場合)は、AssignmentTaskテーブルの外部キー参照をカスケード削除することです。そうすれば、それらの行はタスクを削除すると自動的に削除されます。次に、それらのすべてが処理されたら、割り当てを削除することができます。

+0

私は多くに多くを持っていませんでした、私は簡潔にするためのテーブルの詳細を切り出します。私は 'ON DELET CASCADE'を調べます – Luke

1

あなたが削除する予定のassignment_idに基づいてtask_idを照会してみませんか?

データベースに関連するデータの削除を残すことができますが、あなたが関係を作成したときに、カスケードアクションonDeleteを定義した場合、それは依存しています。

私が知っている限り、カスケードonDeleteを使用する場合は、sqliteで有効にする必要があります。方法については、この記事を参照してください。 Foreign key constraints in Android using SQLite? on Delete cascade

生のクエリを使用できます。例えば

TASK_IDには

を(assignment_id = your_assignment_id_here割り当てからTASK_ID選択)タスクから削除私は、2つの理由Aに対して、このためにトランザクションを使用することをお勧めします)ので、あなたのクエリのインクルードいずれかが失敗した場合にロールバックすることができます。 b)sqliteは、複数のクエリがある場合、一般的にトランザクションを高速に処理します。したがって、トランザクション内の特定のアクションのすべての削除キューを配置します。以下

リンクrawQueryためのものです: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#rawQuery(java.lang.String、[] java.lang.Stringで)

+0

おかげさまで、両方の人が 'ON DELET CASCADE'を有効にすることをお勧めします.1つ以上のクエリが失敗した場合をより適切に処理するためにトランザクションを実装する方法も検討します。 – Luke

関連する問題