sql >> データベース >  >> RDS >> SQLite

SQLiteの既存のテーブルに外部キーを追加する

    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;

    そしてそれは本当です。私の例では、この方法も同様に機能します。

    ただし、このメソッドには、既存のトリガー、ビュー、および外部キー制約内のテーブルへの参照が破損する可能性もあります。

    したがって、テーブルに既存のトリガー、ビュー、または外部キー制約がすでにある場合は、推奨される方法を使用する方がおそらく安全です。


    1. 複数行のMySQLONDUPLICATE KEY UPDATEは、単一のクエリに挿入されます

    2. テキストボックスのテキストを整数に変換する

    3. OracleCloudPlatform上のOracleDatabase12cでのOracleJDeveloper12cの使用、パート1

    4. 2つの日付の日/月/年(datediff)の差を取得するにはどうすればよいですか?