SQLiteは、ALTER TABLE
の非常に限られたサブセットをサポートします 声明。 ALTER TABLE
でできることは SQLiteでは、テーブルの名前を変更したり、テーブル内の列の名前を変更したり、既存のテーブルに新しい列を追加したりします。
つまり、ALTER TABLE
を使用することはできません。 他のデータベース管理システムでできるように、既存のテーブルに外部キーを追加します。
したがって、SQLiteの既存のテーブルに外部キーを「追加」できる唯一の方法は、外部キーを使用して新しいテーブルを作成し、そのデータを新しいテーブルに転送することです。
これを行うには複数の方法がありますが、推奨される方法があります。
推奨される方法
SQLiteのドキュメントでは、テーブルにスキーマを変更するための12ステップのプロセスを推奨しています。
この記事では、外部キーの追加についてのみ説明します。
少し現実的にするために、テーブルにすでにデータが含まれていることを確認します。
外部キーのない元のテーブル
まず、なしでテーブルを作成しましょう 外部キーを入力し、データを入力します。
CREATE TABLE Types(
TypeId INTEGER PRIMARY KEY,
Type
);
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
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つのテーブルを作成し、それらにデータを入力しました。 1つ(タイプ)であるため、2つのテーブル )主キーと他の(ペット )外部キーがあります。
外部キーを作成しなかったことに注意してください。
次のコマンドを実行して、外部キーがないことを確認できます。
PRAGMA foreign_key_list(Pets);
私の場合、次の結果が得られます:
(このテーブルには外部キーの制約がないため、これは空白です。)
それでは、外部キーを「追加」しましょう。
外部キーの追加
次のコードは、外部キー制約を使用して新しいテーブルを作成し、そのテーブルにデータを転送し、元のテーブルを削除してから、新しいテーブルの名前を元のテーブルの名前に変更することで、テーブルに外部キーを追加します。
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
CREATE TABLE Pets_new(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(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
の直前) )。
次に、テーブルで外部キー制約をもう一度確認しましょう。
.mode line
PRAGMA foreign_key_list(Pets);
結果(垂直出力を使用):
id = 0 seq = 0 table = Types from = TypeId to = TypeId on_update = NO ACTION on_delete = NO ACTION match = NONE
今回は、外部キー制約の詳細を確認できます。
コマンドの最初の行(.mode line
)に注意してください )外部キーの作成とは何の関係もありません。ターミナルが結果を出力する方法を変更するためだけに配置しました(結果を表示するために横にスクロールする必要がないようにするため)。
別の方法
前の例を見ると、もっと効率的な方法があると思うかもしれません。たとえば、次のように行うことができます:
PRAGMA foreign_keys = OFF;
BEGIN TRANSACTION;
ALTER TABLE Pets RENAME TO Pets_old;
CREATE TABLE Pets(
PetId INTEGER PRIMARY KEY,
PetName,
TypeId,
FOREIGN KEY(TypeId) REFERENCES Types(TypeId)
);
INSERT INTO Pets SELECT * FROM Pets_old;
DROP TABLE Pets_old;
COMMIT;
PRAGMA foreign_keys = ON;
そしてそれは本当です。私の例では、この方法も同様に機能します。
ただし、このメソッドには、既存のトリガー、ビュー、および外部キー制約内のテーブルへの参照が破損する可能性もあります。
したがって、テーブルに既存のトリガー、ビュー、または外部キー制約がすでにある場合は、推奨される方法を使用する方がおそらく安全です。