[SQLite] insertした直後に登録したデータを取得する方法
最近仕事でSQLiteを使っているので、その時の備忘録です。
SQLでinsertしたデータを取得する時に、該当になるnameやカラムデータを指定して取得してもいいですが、それらがユニークでなければならないので、やはり登録後にid(unique)を取得したいです。
そのため、rowidという登録順に採番されるカラムデータとは別のIDを使って、最新データを取得するのが推奨されています。
last_insert_rowid()またはmax()で最新登録レコードのデータ取得ができる
Testテーブル
今回の検証用に新規にテーブルを作成します。# sqlデータベースにアクセス(ファイルが無くてもアクセスできます)
$ sqlite3 test.sql
# テーブルを作成
sqlite > CREATE TABLE test(id INTEGER PRIMARY KEY, name TEXT);
# 登録されたテーブルの確認
sqlite > SELECT * FROM sqlite_master WHERE type="table";
table|test|test|2|CREATE TABLE test(id INTEGER PRIMARY KEY, name TEXT)
# テストデータの登録
sqlite > INSERT INTO test (name) VALUES ("aaa");
sqlite > INSERT INTO test (name) VALUES ("bbb");
sqlite > INSERT INTO test (name) VALUES ("ccc");
# 登録されたデータ一覧の確認
sqlite > SELECT * FROM test
1|aaa
2|bbb
3|ccc
last_insert_rowid()
sqlite >SELECT * FROM test WHERE rowid=last_insert_rowid();
3|ccc
max()
sqlite >SELECT max(rowid),* FROM test;
3|3|ccc
rowidが取得出来ない確認ポイント
上記のようにコマンドで打ち込んでいると、どれも問題なく結果が出ると思いますが、phpなどでsqliteを使う時に、last_insert_rowid()を使って正常に登録したデータが取得できないケースがありました。 phpでのsqlite登録データの取得方法サンプルを見て、理解してください。ダメパターン
<?php
add();
$data = inserted_data();
print_r($data);
function add(){
$sqlite = new \SQLite3('test.sql');
$res = $sqlite->exec('INSERT INTO test (name) VALUES ("ddd")');
$sqlite->close();
}
function inserted_data(){
$datas = [];
$sqlite = new \SQLite3('test.sql');
$res = $sqlite->query('SELECT * FROM test WHERE rowid=last_insert_rowid()');
while ($row = $res->fetchArray(SQLITE3_ASSOC)) {
array_push($datas , $row);
}
$sqlite->close();
return $datas;
}
データは登録出来ていましたが、結果は取得できていません。
成功パターン
<?php
$data = add();
print_r($data);
function add(){
$datas = [];
$sqlite = new \SQLite3('test.sql');
$sqlite->exec('INSERT INTO test (name) VALUES ("ddd:'.date('YmdHis').'")');
$res = $sqlite->query('SELECT * FROM test WHERE rowid=last_insert_rowid()');
while ($row = $res->fetchArray(SQLITE3_ASSOC)) {
array_push($datas , $row);
}
$sqlite->close();
return $datas;
}
これで正常に登録データを取得することが出来るようになりました。
SQLite3で作成したインスタンスをclose()する前じゃないと、last_insert_rowid()が取得できないようでした。