私はSQLiteを使用しています。これは サポートしていません 既存のテーブルに 制約 を追加します。
だから私はこのようなことをすることはできません(例として):
ALTER TABLE [Customer]
ADD CONSTRAINT specify_either_phone_or_email
CHECK (([Phone] IS NOT NULL) OR ([Email] IS NOT NULL));
このシナリオの回避策はありますか?
知っている:
アイデア
スキーマを変更してテーブルのコピーを作成するには、作成とコピーを手動で行う必要があります。
BEGIN;
CREATE TABLE Customer_new (
[...],
CHECK ([...])
);
INSERT INTO Customer_new SELECT * FROM Customer;
DROP TABLE Customer;
ALTER TABLE Customer_new RENAME TO Customer;
COMMIT;
スキーマを読み取るには、 .schema Customer
コマンドラインシェル でsqlite3
を実行します。これにより、編集および実行できるCREATETABLEステートメントが得られます。
テーブルを所定の位置に変更するには、バックドアを使用できます。
まず、実際のテーブル定義を読み取ります(これは、.schema
から取得するものと同じです)。
SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'Customer';
その文字列にCHECK制約を追加し、 PRAGMA writable_schema = 1; を使用してsqlite_master
への書き込みアクセスを有効にし、新しいテーブル定義をその文字列に書き込みます。
UPDATE sqlite_master SET sql='...' WHERE type='table' AND name='Customer';
次に、データベースを再度開きます。
[〜#〜]警告[〜#〜]:これは、テーブルのディスク上のフォーマットを変更しない変更に対してのみ機能します。レコード形式を変更する変更(フィールドの追加/削除、ROWIDの変更、内部インデックスを必要とする制約の追加など)を行うと、データベースがひどく爆発します。