Android 获取SQLite数据库的下一个自动增量值

Android 获取SQLite数据库的下一个自动增量值,android,sqlite,auto-increment,Android,Sqlite,Auto Increment,使用Android API中典型的SQLiteDatabase对象,我可以做些什么来获取特定列(即id)的下一个AUTO_INCREMENT值,而不影响值本身。有办法吗?或者我应该执行什么查询来获得该结果。请记住,SQLiteDatabase.query()返回一个游标对象,因此如果我只是想从中获取一个值,我不太确定如何直接处理它。你说得对。第一个答案(仍在下面)仅适用于id没有自动增量的情况。使用自动增量,值存储在单独的表中并用于增量。下面是一个查找值的示例: public void prin

使用Android API中典型的SQLiteDatabase对象,我可以做些什么来获取特定列(即
id
)的下一个
AUTO_INCREMENT
值,而不影响值本身。有办法吗?或者我应该执行什么查询来获得该结果。请记住,SQLiteDatabase.query()返回一个
游标
对象,因此如果我只是想从中获取一个值,我不太确定如何直接处理它。

你说得对。第一个答案(仍在下面)仅适用于id没有自动增量的情况。使用自动增量,值存储在单独的表中并用于增量。下面是一个查找值的示例:

public void printAutoIncrements(){
    String query = "SELECT * FROM SQLITE_SEQUENCE";
    Cursor cursor = mDb.rawQuery(query, null);
    if (cursor.moveToFirst()){
        do{
            System.out.println("tableName: " +cursor.getString(cursor.getColumnIndex("name")));
            System.out.println("autoInc: " + cursor.getString(cursor.getColumnIndex("seq")));

        }while (cursor.moveToNext());
    }

    cursor.close(); 

}
见:

第一个答案:

您可以查询_id列的最大值,例如:

String query = "SELECT MAX(id) AS max_id FROM mytable";
Cursor cursor = db.rawQuery(query, null);

int id = 0;     
if (cursor.moveToFirst())
{
    do
    {           
        id = cursor.getInt(0);                  
    } while(cursor.moveToNext());           
}
return id;

这适用于尚未指定为“整型主键自动递增”的行id(所有表都有一个行id列)

关于SQLITE_序列表的一个重要注释

文件上说

每当创建包含自动增量列的普通表时,就会自动创建并初始化SQLITE_序列表

因此,将创建SQLITE_序列表,但不创建与包含AUTOINCREMENT列的表关联的行。该行是使用第一个insert查询创建的(“seq”值为1)


这意味着在查找特定表的下一个自动增量值之前,必须至少执行一个insert操作。例如,可以在创建表之后执行插入和删除虚拟行。

在您使用的SQLiteOpenHelper中,启动事务。插入一些数据,然后回滚

这样,您就可以获得下一行id,如下所示:

public long nextId() {
    long rowId = -1;

    SQLiteDatabase db = getWritableDatabase();
    db.beginTransaction();
    try {
        ContentValues values = new ContentValues();
        // fill values ...

        // insert a valid row into your table
        rowId = db.insert(TABLE_NAME, null, values);

        // NOTE: we don't call  db.setTransactionSuccessful()
        // so as to rollback and cancel the last changes
    } finally {
        db.endTransaction();
    }
    return rowId;
}

这是使用SQLITE获取自动递增主键上最后一个ID的最佳方法


String query=“select seq from sqlite_sequence,其中name='Table_name'”

您可以使用
cursor.getInt(i)方法
i
以下是id列的索引

Cursor c = db.rawQuery("Select * From mSignUp", null);
            String mail = null;
            try {
                while (c.moveToNext()) {
                    mail = c.getString(0);
                    String pas = c.getString(1);
                    Toast.makeText(getApplicationContext(), "Name = " + mail + " Pass = " + pas, Toast.LENGTH_SHORT).show();
                }
            }catch (CursorIndexOutOfBoundsException e){
                Log.e("OutOfBound", Log.getStackTraceString(e));
            }
            finally {
                c.close();
            }

下面是我用来获取特定表的下一个自动增量值的方法:

/**
 * Query sqlite_sequence table and search for the AUTOINCREMENT value for <code>tableName</code>
 * @param tableName The table name with which the AUTOINCREMENT value is associated.
 *
 * @return The next AUTOINCREMENT value for <code>tableName</code>
 * If an INSERT call was not previously executed on <code>tableName</code>, the value 1 will
 * be returned. Otherwise, the returned value will be the next AUTOINCREMENT.
 */
private long getNextAutoIncrement(String tableName) {
    /*
     * From the docs:
     * SQLite keeps track of the largest ROWID using an internal table named "sqlite_sequence".
     * The sqlite_sequence table is created and initialized automatically
     * whenever a normal table that contains an AUTOINCREMENT column is created.
     */
    String sqliteSequenceTableName = "sqlite_sequence";
    /*
     * Relevant columns to retrieve from <code>sqliteSequenceTableName</code>
     */
    String[] columns = {"seq"};
    String selection = "name=?";
    String[] selectionArgs = { tableName };

    Cursor cursor = mWritableDB.query(sqliteSequenceTableName, 
            columns, selection, selectionArgs, null, null, null);

    long autoIncrement = 0;

    if (cursor.moveToFirst()) {
        int indexSeq = cursor.getColumnIndex(columns[0]);
        autoIncrement = cursor.getLong(indexSeq);
    }

    cursor.close();

    return autoIncrement + 1;
}
这是工作

public static long getNextId(SQLiteDatabase db, String tableName) {
    Cursor c = null;
    long seq = 0;
    try {
        String sql = "select seq from sqlite_sequence where name=?";
        c = db.rawQuery(sql, new String[] {tableName});
        if (c.moveToFirst()) {
            seq = c.getLong(0);
        }
    } finally {
        if (c != null) {
            c.close();
        }
    }
    return seq + 1;
}

表的最大id不一定是自动增量值,因为如果删除了id较高的行会怎么样?获取最大id是不正确的。@aha显然,您可以使用cursor.getCount()并递增其值,并将其存储为自动递增值……@hanry cursor.getCount()每次都很可能是错误的方法:任何时候从表中删除一行。对于没有自动递增行id的表,默认行id从最大值递增。在尝试执行此操作之前,我们必须检查是否有任何行被插入到此表中,如果我们没有返回某个常量id
cursor。moveToFirst()
为false尝试获取此值是一种错误的设计模式。您试图完成的是什么?是的,在尝试获取下一个增量值之前,我们只需检查是否可以移动到First或getCount,就可以知道,如果插入ID为´autoIncrement+1´的记录,然后插入没有指定ID的记录,会发生什么情况?例如:sequence=9,在本例中返回10,并插入ID=10(指定)的记录。然后,插入一条新记录而不指定ID。SQLite知道他必须为ID插入11吗?或者他会尝试插入10并导致错误?