通常、SQLで外部キーを削除する必要がある場合は、ALTER TABLE
を使用します。 声明。ただし、SQLiteを使用している場合、それはオプションではありません。
SQLiteは、ALTER TABLE
の非常に限られたサブセットをサポートします 声明。 ALTER TABLE
でできることは SQLiteでは、テーブルの名前を変更したり、テーブル内の列の名前を変更したり、既存のテーブルに新しい列を追加したりします。
つまり、ALTER TABLE
を使用することはできません。 他のRDBMSでできるように外部キーをドロップするには
SQLiteで外部キーを「ドロップ」するための推奨される方法は、実際には、外部キーなしで(または、必要に応じて別のテーブルを使用して)データを新しいテーブルに転送することです。
推奨される方法
SQLiteのドキュメントでは、テーブルにスキーマを変更するための12ステップのプロセスを推奨しています。次の例では、そのプロセスを使用して外部キーを「ドロップ」します。
外部キーを使用してテーブルを作成する
まず、外部キーを使用してテーブルを作成し、データを入力します。
CREATE TABLE Types(
TypeId INTEGER PRIMARY KEY,
Type
);
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);
INSERT INTO Types VALUES
( NULL, 'Dog' ),
( NULL, 'Cat' ),
( NULL, 'Parakeet' ),
( NULL, 'Hamster' );
INSERT INTO Pets VALUES
( NULL, 'Brush', 3 ),
( NULL, 'Tweet', 3 ),
( NULL, 'Yelp', 1 ),
( NULL, 'Woofer', 1 ),
( NULL, 'Fluff', 2 );
実際、ここで2つのテーブルを作成し、それらにデータを入力しました。最初のテーブル(タイプ)のため、2つのテーブル )主キーと他の(ペット )外部キーを持っています。 2番目のテーブルの最後の行に外部キーが追加されました。
次のコマンドを実行することで、外部キーが作成されたことを確認できます。
PRAGMA foreign_key_list(Pets);
結果:
id seq table from to on_update on_delete match -- --- ----- ------ ------ --------- --------- ----- 0 0 Types TypeId TypeId NO ACTION NO ACTION NONE
外部キー制約の詳細を確認できます。
それでは、外部キーを「ドロップ」しましょう。
外部キーを「ドロップ」する
次のコードは、外部キー制約なしで新しいテーブルを作成し、そのテーブルにデータを転送し、元のテーブルを削除してから、新しいテーブルの名前を元のテーブルの名前に変更することで、外部キーを「削除」します。
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
CREATE TABLE Pets_new(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId
);
INSERT INTO Pets_new SELECT * FROM Pets;
DROP TABLE Pets;
ALTER TABLE Pets_new RENAME TO Pets;
COMMIT;
PRAGMA foreign_keys = ON;
完了しました。
インデックス、トリガー、またはビューを再構築する必要がある場合は、ALTER TABLE
の後に再構築してください。 テーブルの名前を変更するステートメント(COMMIT
の直前) )。
次に、テーブルで外部キー制約をもう一度確認しましょう。
PRAGMA foreign_key_list(Pets);
結果:
(このテーブルには外部キーの制約がないため、これは空白です。)
同じ方法を使用して、既存のテーブルに外部キーを追加できます。
別の方法
前の例を見ると、もっと効率的な方法があると思うかもしれません。たとえば、次のように行うことができます:
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
ALTER TABLE Pets RENAME TO Pets_old;
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId
);
INSERT INTO Pets SELECT * FROM Pets_old;
DROP TABLE Pets_old;
COMMIT;
PRAGMA foreign_keys = ON;
そしてそれは本当です。私の例では、この方法も同様に機能します。
ただし、このメソッドには、既存のトリガー、ビュー、および外部キー制約内のテーブルへの参照が破損する可能性もあります。
したがって、テーブルに既存のトリガー、ビュー、または外部キー制約がすでにある場合は、推奨される方法を使用する方がおそらく安全です。