データベースを開いた直後に、特定のテーブルの最後の自動インクリメント値を取得するにはどうすればよいですか?last_insert_rowid()
挿入トランザクションがないからではありません。つまり、特定のテーブルに新しい行を挿入するときに自動インクリメントが選択する数値を事前に知りたいのです。
2 に答える
自動インクリメント列がどのように定義されているかによって異なります。
列の定義が の場合、INTEGER PRIMARY KEY AUTOINCREMENT
SQLite は最大の ID を という内部テーブルに保持しますsqlite_sequence
。
列定義にキーワードが含まれていない場合AUTOINCREMENT
、SQLite は「通常の」ルーチンを使用して新しい ID を決定します。ドキュメントから:
通常のアルゴリズムでは、新しく作成された行に、挿入前のテーブル内の最大の ROWID よりも 1 大きい ROWID を指定します。テーブルが最初に空の場合、1 の ROWID が使用されます。最大の ROWID が可能な最大の整数 (9223372036854775807) と等しい場合、データベース エンジンは、以前に使用されていないものを見つけるまで、正の候補の ROWID をランダムに選択し始めます。適切な回数試行しても未使用の ROWID が見つからない場合、挿入操作はSQLITE_FULLエラーで失敗します。負の ROWID 値が明示的に挿入されない場合、自動的に生成される ROWID 値は常にゼロより大きくなります。
AUTOINCREMENT
のない列の場合、次の ID を決定する唯一の確実な方法は、最初にデータベースをVACUUMすることだと読んだことを覚えています。これにより、すべての ID カウンターがそのテーブルの既存の最大 ID + 1 にリセットされます。
そうは言っても、特に別のプロセスが同時にデータベースに書き込む可能性がわずかにある場合は特に、自動インクリメントされた ID を事前に取得することは悪い考えであるというslash_rick_dotに同意します。
データベースが異なれば、自動インクリメントの実装も異なります。しかし、私の知る限り、あなたの質問に答えてくれる人は誰もいません。
自動インクリメント機能は、新しく追加されたテーブル行に一意の ID を作成することを目的としています。行がまだ挿入されていない場合、機能は ID を生成していません。
そして、それは理にかなっています...次の自動インクリメント番号を取得した場合、それをどうしますか? おそらくその意図は、まだ挿入されていない新しい行の主キーとして割り当てることです。しかし、ID を取得してからそれを使用して行を挿入するまでの間に、データベースはその ID を使用して別のプロセスの行を挿入できた可能性があります。
選択肢は次のとおりです。ID の作成を自分で管理するか、行が挿入されるまで待ってから自動作成された識別子を使用します。