はじめに
この実験 (lab) では、SQLite データベースで効果的にエラーを処理する方法を学びます。主な焦点は、ON CONFLICT 句を使用して INSERT 操作中の制約違反を管理することです。
まず、データベースと UNIQUE 制約を持つテーブルを作成します。次に、競合が発生した場合に実行できるさまざまなアクション(ROLLBACK、ABORT、FAIL、IGNORE、または REPLACE など)を検討します。特に、ON CONFLICT IGNORE を使用して、一意性制約に違反した場合の挿入を防ぎます。この実験 (lab) では、データの挿入と潜在的なエラーの処理に関する実践的な例を通して説明します。
SQLite データベースと UNIQUE 制約を持つテーブルの作成
このステップでは、SQLite データベースと UNIQUE 制約を持つテーブルを作成します。この制約は、重複したデータを挿入する際のエラー処理方法を理解するのに役立ちます。
まず、LabEx VM でターミナルを開きます。デフォルトのパスは /home/labex/project です。
次に、my_database.db という名前の SQLite データベースを作成しましょう。次のコマンドを実行して、データベースファイルを作成し、SQLite コマンドラインツールを開きます。
sqlite3 my_database.db
SQLite シェル内に入ったことを示すプロンプトが表示されます。
SQLite version 3.x.x
Enter ".help" for usage hints.
sqlite>
次に、ユーザー情報を格納するための users という名前のテーブルを作成します。このテーブルには、id、username、および email の 3 つの列があります。username 列には UNIQUE 制約があり、各ユーザー名はテーブル内で一意である必要があります。sqlite> プロンプトで次の SQL コマンドを入力し、Enter キーを押します。
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT NOT NULL
);
このコマンドは、users テーブルを次のように設定します。
idは、新しいエントリごとに自動的に増加する整数です。PRIMARY KEY制約により、各idが一意であることが保証され、AUTOINCREMENTにより自動的に増加します。usernameは、空にすることができず (NOT NULL)、一意である必要があるテキストフィールドです (UNIQUE)。emailも、空にすることができないテキストフィールドです (NOT NULL)。
コマンドが正常に実行された場合、出力は表示されません。
テーブルへのデータ挿入
users テーブルを作成したので、いくつかのデータを追加してみましょう。ユーザーレコードをテーブルに挿入します。
sqlite> プロンプトで次のコマンドを実行して、ユーザーレコードを users テーブルに挿入します。
INSERT INTO users (username, email) VALUES ('Alice', 'alice@example.com');
このコマンドは、users テーブルに行を追加します。
INSERT INTO users (username, email)は、usersテーブルのusername列とemail列にデータを挿入することを指定します。VALUES ('Alice', 'alice@example.com')は、各レコードに挿入される値を提供します。
データが正しく追加されたことを確認するには、次のコマンドを実行して、テーブル内のすべてのレコードを表示します。
SELECT * FROM users;
期待される出力 (Expected Output):
1|Alice|alice@example.com
この出力は、レコードの id、username、および email を示しています。SELECT * コマンドは、指定されたテーブルからすべての列を取得します。
重複データの挿入を試みる
このステップでは、重複したユーザー名を持つレコードを挿入しようとします。これにより、UNIQUE 制約に違反し、エラーが発生します。
sqlite> プロンプトで次のコマンドを実行します。
INSERT INTO users (username, email) VALUES ('Alice', 'alice2@example.com');
次のようなエラーメッセージが表示されます。
Error: UNIQUE constraint failed: users.username
このエラーメッセージは、username 列の UNIQUE 制約に違反したことを示しています。SQLite は、データの整合性を維持するために、重複したユーザー名の挿入を防ぎます。
ON CONFLICT IGNORE を使用して制約違反を処理する
このステップでは、ON CONFLICT IGNORE 句を使用して制約違反を処理する方法を学びます。この句は、制約に違反する場合、SQLite に挿入を無視するように指示します。
sqlite> プロンプトで次のコマンドを実行します。
INSERT OR IGNORE INTO users (username, email) VALUES ('Alice', 'alice2@example.com');
このコマンドは、ユーザー名 'Alice' を持つ新しいレコードを挿入しようとします。ただし、ON CONFLICT IGNORE 句が使用されているため、SQLite は挿入を無視し、エラーは発生しません。
重複レコードが挿入されなかったことを確認するには、次のコマンドを実行します。
SELECT * FROM users;
期待される出力 (Expected Output):
1|Alice|alice@example.com
出力は、ユーザー名 'Alice' を持つ元のレコードのみがテーブルに存在することを示しています。重複レコードは無視されました。
INSERT OR IGNORE ステートメントは、制約に違反する可能性のあるデータを挿入するときに、エラーを防ぎ、データの整合性を維持する方法を提供します。
ON CONFLICT REPLACE を使用して制約違反を処理する
このステップでは、ON CONFLICT REPLACE 句を使用して制約違反を処理する方法を学びます。この句は、制約に違反する場合、SQLite に既存のレコードを新しいレコードで置き換えるように指示します。
sqlite> プロンプトで次のコマンドを実行します。
INSERT OR REPLACE INTO users (id, username, email) VALUES (1, 'Alice', 'alice3@example.com');
このコマンドは、ユーザー名 'Alice' を持つ新しいレコードを挿入しようとします。ON CONFLICT REPLACE 句が使用されているため、SQLite は既存のレコードを新しいレコードで置き換えます。REPLACE は古い行を削除して新しい行を挿入するため、この場合は id を指定する必要があることに注意してください。
レコードが置き換えられたことを確認するには、次のコマンドを実行します。
SELECT * FROM users;
期待される出力 (Expected Output):
1|Alice|alice3@example.com
出力は、ユーザー名 'Alice' を持つレコードのメールアドレスが alice3@example.com に更新されたことを示しています。
INSERT OR REPLACE ステートメントは、データの整合性を維持しながら既存のレコードを更新する方法を提供します。
最後に、SQLite シェルを終了します。
.exit
これにより、データベース接続が閉じられ、ターミナルに戻ります。
まとめ
この実験 (lab) では、SQLite データベースで効果的にエラーを処理する方法を学びました。特に、INSERT 操作中の制約違反に焦点を当てました。データベースと UNIQUE 制約を持つテーブルを作成し、データを挿入した後、重複データを挿入してエラーを発生させようとしました。次に、ON CONFLICT IGNORE および ON CONFLICT REPLACE 句を使用してこれらの制約違反を処理する方法を検討し、SQLite が潜在的なエラーにどのように対応するかを制御し、データの整合性を維持できるようにしました。


