概要
SQLite 3 では OracleやMySQLのように「ALTER TABLE~」で外部キー制約を削除することができない。
(ver 3.34.1 時点)
そのため少し面倒な手順をとる必要がある。
詳細
SQLiteのテーブルの構成を変更する方法として、 テーブルを作り直してデータを移行する方法 があるが、既存のカラムの外部キー制約を削除するだけであればもう少し簡単な方法がある。
基本的には 既存のカラムに外部キー制約を設定する方法 と同様の流れになる。
公式(英語) に手順が記載されている。
- トランザクションを開始。
- Pragma schema_versionでスキーマのバージョンを確認する。
- Pragma writable_schema=onにする。
- sqlite_schemaテーブルに保存されているスキーマ文を更新する。
-
他のテーブルに影響が出る場合はそちらにも変更を加える。
(外部キー制約を追加するだけであれば不要。) - Pragma schema_version=Xでスキーマのバージョンを+1する。
- Pragma writable_schema=offにする。
- Pragma Integrity_checkを実行してデータベースが壊れていないか確認する。
- トランザクションをコミットする。
実行例
以下は「receipt」テーブルの「product_id」から外部キー制約を削除する例。
実行環境
- Windows 10 64bit
- SQLite Command-Line Shell ver 3.34.1
実行手順
- トランザクションを開始
- スキーマのバージョンを確認
- スキーマを編集可能にする
- 現在のスキーマを確認する
-
スキーマテーブルを更新してproduct_idから外部キー制約を削除する。
スキーマ文は「sqlite_schema」というテーブルに登録されているため、 これをupdateしてやればいい。 - 「.schema」コマンドでスキーマが変更されたことを確認する
- スキーマのバージョンを一つ上げる
- スキーマを編集不能に戻す
- データベースが壊れていないかチェックする
- トランザクションをコミットする
sqlite> --# 1.
sqlite> begin transaction;
sqlite> --# 2.
sqlite> pragma schema_version;
2
sqlite> --# 3.
sqlite> pragma writable_schema=on;
sqlite> --# 4.
sqlite> .schema receipt
CREATE TABLE receipt (
row_num number
, create_date text
, product_id number references product(product_id)
, quantity text
);
sqlite> --# 5.
sqlite> update
...> sqlite_schema
...> set
...> sql=
...> 'create table receipt (
...> row_num number
...> , create_date text
...> , product_id number
...> , quantity text
...> )'
...> where
...> tbl_name = 'receipt'
...> ;
sqlite> --# 6.
sqlite> .schema receipt
create table receipt (
row_num number
, create_date text
, product_id number
, quantity text
);
sqlite> --# 7.
sqlite> pragma schema_version=3;
sqlite> --# 8.
sqlite> pragma writable_schema=off;
sqlite> --# 9.
sqlite> pragma Integrity_check;
ok
sqlite> --#10.
sqlite> commit;
参考URL
-
SQLite Foreign Key Support
SQLite 公式の外部キーに関するドキュメント(英語)
https://www.sqlite.org/foreignkeys.html -
ALTER TABLE
SQLite 公式のテーブル変更に関するドキュメント(英語)
https://www.sqlite.org/lang_altertable.html
-
あさはか備忘録: SQLite 3 外部キー制約のあるテーブルを作成する
https://sfnovicenotes.blogspot.com/2020/01/sqlite3.html -
あさはか備忘録: SQLite 3 テーブルのスキーマ文を編集する
https://sfnovicenotes.blogspot.com/2021/01/sqlite-3.html -
あさはか備忘録: SQLite 3 既存のカラムに外部キー制約を設定する
https://sfnovicenotes.blogspot.com/2021/02/sqlite-3_21.html