3

再帰結合を持つ単一テーブル データベースで参照整合性を維持するために、SQLite で外部キー サポートを使用しようとしています。

例えば

PRAGMA foreign_keys = ON;

create table tree (
  objectId text unique not null,
  parentObjectID text,
  foreign key (parentObjectID) references tree(parentObjectID) on delete cascade
)

私が望んでいる動作は、親行が削除されると、その子とその子も削除されることです。

ただし、ルート行を削除しようとすると (データベース内の他のすべての行も削除されることが予想される場合)、次のエラーが発生します。

sqlite> delete from tree where objectid = '0';
Error: foreign key mismatch

私の期待は、SQLite の外部キー サポート (および削除動作) が提供できるものとは違っていますか?

4

1 に答える 1

2

あなたの問題は非常に単純です.FKはparentObjectId参照parentObjectIdではなくobjectId、テーブルを使用しようとするまでSQLiteはこの混乱を検出しません. FK が次のように定義されている場合:

foreign key (parentObjectID) references tree(objectID) on delete cascade

細かいマニュアルから:

したがって、言い換えると、子と親の両方を確認する必要がある誤って構成された外部キー制約は、DML エラーです。外部キー DML エラーの英語のエラー メッセージは、通常は「外部キーの不一致」ですが、親テーブルが存在しない場合は「そのようなテーブルはありません」になることもあります。次の場合、外部キー DML エラーが報告されることがあります。

  • 親テーブルが存在しない、または
  • 外部キー制約で指定された親キー列が存在しないか、または
  • 外部キー制約で指定された親キー列が親テーブルの主キーではなく、CREATE TABLE で指定された照合順序を使用する一意制約の対象ではない、または
  • 子テーブルが主キー列を指定せずに親の主キーを参照しており、親の主キー列の数が子キー列の数と一致していません。

3 番目のポイントは、PK でも一意であるという制約でもないため、ここで適用されるように思われるparentObjectIdため、テーブルの内容を変更しようとする (つまり、DDL ステートメントではなく DML ステートメントを使用する) までエラーは表示されません。

于 2013-01-12T20:50:57.600 に答える