【保存版】Android SQLite で INSERT 後に生成された ID を取得する 7 つのポイント

2024-04-02

ここでは、Android SQLite で INSERT 後に生成された ID を取得する 2 つの方法を紹介します。

lastInsertRowId() メソッドを使用する

SQLiteDatabase クラスには、lastInsertRowId() というメソッドがあります。このメソッドは、最後に挿入されたデータの ID を返します。

// データベースへの接続
SQLiteDatabase db = getWritableDatabase();

// INSERT 文の実行
ContentValues values = new ContentValues();
values.put("name", "John Doe");
long rowId = db.insert("users", null, values);

// 生成された ID の取得
long id = db.lastInsertRowId();

// データベースのクローズ
db.close();

rawQuery() メソッドを使用する

SQLiteDatabase クラスには、rawQuery() というメソッドもあります。このメソッドは、SQL クエリを実行し、その結果をカーソルとして返します。

// データベースへの接続
SQLiteDatabase db = getWritableDatabase();

// INSERT 文の実行
ContentValues values = new ContentValues();
values.put("name", "John Doe");
db.insert("users", null, values);

// 生成された ID の取得
String sql = "SELECT last_insert_rowid()";
Cursor cursor = db.rawQuery(sql, null);
cursor.moveToFirst();
long id = cursor.getLong(0);

// カーソルのクローズ
cursor.close();

// データベースのクローズ
db.close();

どちらの方法でも、最後に挿入されたデータの ID を取得することができます。

補足

  • lastInsertRowId() メソッドは、最後に挿入されたデータの ID を 直接 取得することができます。
  • rawQuery() メソッドは、last_insert_rowid() という SQL 関数を使用して、最後に挿入されたデータの ID を 間接的に 取得することができます。



MainActivity.java

package com.example.sample;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private EditText nameEditText;
    private TextView idTextView;

    private SQLiteOpenHelper helper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        nameEditText = findViewById(R.id.name_edit_text);
        idTextView = findViewById(R.id.id_text_view);

        helper = new MyOpenHelper(this);
    }

    public void onInsertClick(View view) {
        String name = nameEditText.getText().toString();

        SQLiteDatabase db = helper.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put("name", name);

        long rowId = db.insert("users", null, values);

        // lastInsertRowId() メソッドを使用する
        long id1 = db.lastInsertRowId();

        // rawQuery() メソッドを使用する
        String sql = "SELECT last_insert_rowid()";
        Cursor cursor = db.rawQuery(sql, null);
        cursor.moveToFirst();
        long id2 = cursor.getLong(0);

        cursor.close();
        db.close();

        idTextView.setText("ID1: " + id1 + "\nID2: " + id2);
    }
}

MyOpenHelper.java

package com.example.sample;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class MyOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;

    public MyOpenHelper(Context context) {
        super(context, "sample.db", null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE users (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // データベースのアップグレード処理
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/name_edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="名前" />

    <Button
        android:id="@+id/insert_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="挿入"
        android:onClick="onInsertClick" />

    <TextView
        android:id="@+id/id_text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

このサンプルコードを実行すると、ユーザーが入力した名前のデータが SQLite データベースに挿入され、生成された ID が idTextView に表示されます。




その他の ID 取得方法

_id カラムを使用する

SQLite データベースのテーブルに _id という名前のカラムを追加すると、そのカラムに自動的に生成された ID が格納されます。

// データベースへの接続
SQLiteDatabase db = getWritableDatabase();

// INSERT 文の実行
ContentValues values = new ContentValues();
values.put("name", "John Doe");
long rowId = db.insert("users", null, values);

// 生成された ID の取得
long id = values.getAsLong("_id");

// データベースのクローズ
db.close();

rowid 関数を使用する

SELECT 文の rowid 関数を使用して、挿入したデータの ID を取得することができます。

// データベースへの接続
SQLiteDatabase db = getWritableDatabase();

// INSERT 文の実行
ContentValues values = new ContentValues();
values.put("name", "John Doe");
db.insert("users", null, values);

// 生成された ID の取得
String sql = "SELECT rowid FROM users WHERE name = 'John Doe'";
Cursor cursor = db.rawQuery(sql, null);
cursor.moveToFirst();
long id = cursor.getLong(0);

// カーソルのクローズ
cursor.close();

// データベースのクローズ
db.close();

これらの方法は、lastInsertRowId() メソッドや rawQuery() メソッドよりもシンプルですが、_id カラムの存在や SELECT 文の書き方に依存するため、注意が必要です。

Android SQLite で INSERT 後に生成された ID を取得するには、いくつかの方法があります。どの方法を使用するかは、開発者の好みや状況によって異なります。


java android sqlite


【完全網羅】SQLiteでNULL値を含む列にユニーク制約を設定する3つの方法と注意点

通常のUNIQUE制約では、すべての列に値が入力されている必要があるため、NULL値を含む列には設定できません。しかし、擬似列と呼ばれる特殊な列を使用することで、NULL値を含む複数の列にユニーク制約を設定することができます。擬似列の作成: まず、ユニーク制約を設定したい列の値を結合した文字列を保持する擬似列を作成します。 この擬似列は、テーブル定義内にVIRTUALキーワードを使用して作成します。...


SQLiteデータベースのロックに関するトラブルシューティング

ここでは、SQLiteデータベースをロックする方法について、いくつかの方法を紹介します。排他ロックは、データベース全体をロックする方法です。他のプロセスは、ロックが解除されるまで、データベースへの読み書きアクセスを行うことができません。排他ロックを取得するには、以下の方法があります。...


SQLiteの同時アクセスをライブラリで解決:便利なツール集

排他ロックと共有ロックSQLiteは、データベースファイルへのアクセスを制御するために、排他ロックと共有ロックという2種類のロックメカニズムを使用します。排他ロック: 排他ロックを持っているプロセスは、データベースファイルに対して読み取りと書き込みの両方の操作を実行できます。他のプロセスは、そのロックが解除されるまで、同じデータベースファイルを操作できません。...


SQLiteでPRIMARY KEYとUNIQUE制約を組み合わせる際の注意点とは?

主キー (PRIMARY KEY)その列の値は、テーブル内のすべての行で 一意 でなければなりません。つまり、同じ値を持つ行は存在できません。その列の値は NULL であることができません。テーブルに複数の主キー列を設定することはできません。...