|
|
前のページ 1 2 3
|
|
INSERTしたIDの取得
|
少し戻って、exec()で実行するINSERTクエリの例に戻りましょう。多くのデータベースシステムはINSERTされる度に増加するオートインクリメントなIDをサポートしています。このIDを使用してソートを行うことで、素早く簡単にレコードを特定できます。
MySQLではINTEGERAUTO_INCREMENT PRIMARYKEY、SQLiteはとてもシンプルでINTEGER PRIMARY KEY、そしてPostgreSQLではSERIAL型のカラムにシーケンスを付加することで設定されます。
INSERTされたレコードは他のデータと関連付けられるので共通の動作でこの値を取り出すことができます。PDOはこの値をスムーズに取り出せるようにlastInsertId()メソッドを用意しています。このメソッドは、最後にINSERTされたレコードのPRIMARY KEYの値を返します。
|
$db->exec("CREATE TABLE my_table ". "(id INTEGER PRIMARY KEY, a INT,b INT,c INT");
$db->exec("INSERT INTO my_table (a,b,c)VALUES(1,2,3)");
$id = $db->lastInsertId();
|
使用するデータベースがPostgreSQLの場合、この機能は少し独特なものになります。標準では返される値は、それぞれのテーブルに割り当てられた内部カウンターのOIDのIDです。この値は現在のSERIAL型カラムのシーケンスの値とは違う値です。しかしこれは下記のクエリを使用することで解決できます。
|
$oid = $db->lastInsertId();
$q = "SELECT id FROM tbl_name WHERE oid={$oid}";
$id = $db->query($q)->fetchColumn();
|
しかし、これはかなり不便で、クエリを実行してその結果から値を取得するという余計な処理があるので若干遅くなります。この状況を改善するには、PostgreSQL ドライバの著者がlastInserID()メソッドにシーケンス名を入力する引数を追加することです。
この引数を指定することで、lastInsertID()メソッドの内部のコードで直接シーケンスにクエリを発行し、期待されるIDの値を返す関数とすることができます。シーケンス名は、通常はデータベースが自動的にテーブル名に基づいて作成するので予想することができます。
例えば、カラム名がid、テーブル名がfooだとすると、生成されるシーケンス名はfoo_id_seqになるはずです。
|
トランザクション
|
INSERTやUPDATEのようなデータベースの情報を変更する場合、実行中の一貫性を保つ必要があります。これを解決する1つの方法は、全体の一貫性を保つトランザクションにクエリをまとめることです。
トランザクションの他の利点は、アンドゥ機能が使用できること、クエリの実行中にエラーが発生した場合にトランザクションをロールバックすることができることなどです。
これは影響を受けたテーブルをトランザクション開始時の状態に戻します。また、逆にすべてのクエリの実行に成功すると、コミットを行うことで変更がデータベースに適用されます。トランザクションの使用をサポートするために、PDOは3つの関数を提供しています。
|
while (1) {
$db->beginTransaction(); // トランザクションの開始
for ($i =0; $i < 10; $i++) {
if ($db->exec("INSERT INTO foo …") ===
FALSE) {
$db->rollBack(); // クエリが失敗、中断
break 2;
}
}
$db->commit();
break;
}
|
beginTransaction()メソッドは、その名が示す通り新しいトランザクションを初期化し、内部でいくつものクエリが実行できるようになります。クエリが失敗した場合、トランザクションはrollBack()メソッドを呼び出すことで中断し、エラーが起きなかったらクエリはcommit()メソッドによって保存されます。
|
前のページ 1 2 3
|
|
|
|
著者プロフィール
Ilia Alshanetsky
PHP開発チームの活動メンバーの1人であり、現在のPHP 4.3.X.のリリースマネージャー。また、オープンソース掲示板FUDフォーラム(http://fud.prohost.org/forum/)をはじめとする数多くのプロジェクトにも貢献している。
|
|
|
|