2011-08-05 21 views
9

Utilizando el objeto SQLiteDatabase típico en la API de Android, ¿qué puedo hacer para obtener el siguiente valor AUTO_INCREMENT de una columna particular (es decir, id) sin afectar el valor en sí. ¿Hay un método para eso? O qué consulta debo ejecutar para obtener ese resultado. Tenga en cuenta que SQLiteDatabase.query() devuelve un objeto Cursor, por lo que no estoy muy seguro de cómo lidiar con eso directamente si solo quiero obtener un valor de esto.Obtener el siguiente valor AUTO_INCREMENT de una base de datos SQLite

+0

Intentar obtener este valor es un mal patrón de diseño desde el primer momento. ¿Qué es lo que estás tratando de lograr? – Tim

Respuesta

12

Tienes razón. La primera respuesta (aún más abajo) solo funciona sin AUTOINCREMENT para id. Con AUTOINCREMENT, los valores se almacenan en una tabla separada y se usan para el incremento. He aquí un ejemplo de encontrar el valor:

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(); 

} 

Ver: http://www.sqlite.org/autoinc.html

Primera Respuesta:

Se pueden realizar consultas para el máximo de la columna _ID, tales como:

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; 

Esto funciona para identificadores de filas que no se han especificado como "INTEGER PRIMARY KEY AUTOINCREMENT" (todas las tablas tienen una columna de Id. De fila).

+0

El ID máximo de la tabla puede no ser necesariamente el valor AUTO_INCREMENT porque, ¿qué pasa si se eliminaron las filas con una identificación más alta? Obtener el ID máximo no sería correcto. – Brian

+0

@aha obviamente puede usar ** cursor.getCount() ** e incrementar su valor y almacenarlo como valor de incremento automático ....... – Hanry

+1

@hanry cursor.getCount() probablemente sea el enfoque incorrecto cada vez: cada vez que se borra una fila de la tabla. Para tablas sin una identificación de fila de autoincrement, la identificación de fila predeterminada se incrementa desde el máximo. – aha

3

Una observación importante sobre la tabla SQLITE_SEQUENCE.

La documentación dice

La tabla SQLITE_SEQUENCE se crea e inicializa automáticamente cada vez que se crea una tabla normal que contiene una columna de incremento automático.

Así se crea la tabla SQLITE_SEQUENCE, pero NO la fila asociada a la tabla que contiene la columna AUTOINCREMENT. Esa fila se crea con la primera consulta de inserción (con el valor "seq" de 1).

Eso significa que debe hacer al menos una operación de inserción antes de buscar el siguiente valor de autoincremento de una tabla específica. Podría hacerse, por ejemplo, justo después de la creación de la tabla, realizando una inserción y una eliminación de una fila ficticia.

1

Dentro del SQLiteOpenHelper que utiliza, inicie una transacción. Inserta algunos datos y luego retrocede.

tal manera, usted será capaz de obtener la siguiente fila de identificación, así:

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; 
} 
4

Esta es la mejor manera de conseguir el último ID de incremento automático PRIMARY KEY con SQLITE

String query = "select seq from sqlite_sequence WHERE name = 'Table_Name'"

0

puede utilizar cursor.getInt(i); método
i aquí es el índice de la columna 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(); 
      } 
1

Esto es lo que utilizo para obtener el siguiente valor AutoIncrement para una tabla específica:

/** 
* 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 equal to the value of the current 
* AUTOINCREMENT + 1. 
*/ 
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 = {"name", "seq"}; 

    Cursor cursor = mWritableDatabase.query(sqliteSequenceTableName, columns, null, null, null, null, null); 

    long autoIncrement = 0; 
    /* 
    * We can indeed fail here (If an insert call was not previously executed on <code>tableName</code>), 
    * but no worries: 
    * <code>autoIncrement + 1</code> will be returned either way. 
    */ 
    if (cursor.getCount() > 0) { 
     int indexName = cursor.getColumnIndex(columns[0]); 
     int indexSeq = cursor.getColumnIndex(columns[1]); 

     while (cursor.moveToNext()) { 
      /* 
      * Are we currently looking at <code>tableName</code> ? 
      */ 
      if (cursor.getString(indexName).equals(tableName)) { 
       /* Great, take the AUTOINCREMENT value and get out */ 
       autoIncrement = cursor.getLong(indexSeq); 
       break; 
      } 
     } 
    } 

    cursor.close(); 

    return autoIncrement + 1; 
} 
0

Es un trabajo.

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; 
} 
Cuestiones relacionadas