Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

    
            
  •              ¿Cómo obtener el ID de inserción en JDBC?                                      12 respuestas                          
  •     
    

¿Hay alguna manera de obtener un valor de la última fila insertada?

Estoy insertando una fila donde el PK aumentará automáticamente, y me gustaría obtener este PK. Solo se garantiza que la PK sea única en la tabla.

Estoy usando Java con un JDBC y PostgreSQL.

¿Fue útil?

Solución

Con PostgreSQL puede hacerlo a través de la palabra clave RETURNING:

PostgresSQL - RETURNING

INSERT INTO mytable( field_1, field_2,... )
VALUES ( value_1, value_2 ) RETURNING anyfield

Devolverá el valor de " anyfield " ;. " cualquier campo " Puede ser una secuencia o no.

Para usarlo con JDBC, haz:

ResultSet rs = statement.executeQuery("INSERT ... RETURNING ID");
rs.next();
rs.getInt(1);

Otros consejos

Consulte la documentación de la API para java.sql.Statement .

Básicamente, cuando llama a executeUpdate () o executeQuery () , use la constante Statement.RETURN_GENERATED_KEYS . Luego puede llamar a getGeneratedKeys para obtener las claves generadas automáticamente de todas las filas creadas por esa ejecución. (Suponiendo que su controlador JDBC lo proporcione).

Va ??algo parecido a esto:

Statement stmt = conn.createStatement();
stmt.execute(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet keyset = stmt.getGeneratedKeys();

Si está utilizando JDBC 3.0, puede obtener el valor de PK tan pronto como lo insertó.

Aquí hay un artículo que habla sobre cómo: https://www.ibm .com / developerworks / java / library / j-jdbcnew /

Statement stmt = conn.createStatement();
// Obtain the generated key that results from the query.
stmt.executeUpdate("INSERT INTO authors " +
                   "(first_name, last_name) " +
                   "VALUES ('George', 'Orwell')",
                   Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if ( rs.next() ) {
    // Retrieve the auto generated key(s).
    int key = rs.getInt(1);
}

Desde la versión del controlador JDBC de PostgreSQL 8.4-701 the PreparedStatement # getGeneratedKeys () finalmente es completamente funcional. Lo usamos aquí casi un año en producción a nuestra entera satisfacción.

En " llano JDBC " el PreparedStatement se debe crear de la siguiente manera para que sea posible devolver las claves:

statement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);

Puede descargar la versión actual del controlador JDBC aquí (que aún se encuentra en este momento) 8.4-701).

Las secuencias en postgresql son seguras para transacciones. Así que puedes usar el

currval(sequence)

Cita:

  

currval

     
    

Devuelve el valor obtenido más recientemente por nextval para esta secuencia     En la sesión actual. (Un error es     Informado si nextval nunca ha sido     Llamado para esta secuencia en este     sesión.) Note que porque esto es     devolviendo un valor de sesión local,     da una respuesta predecible incluso si     Otras sesiones se están ejecutando nextval     mientras tanto.

  

Aquí es cómo lo resolví, basado en las respuestas aquí:

Connection conn = ConnectToDB(); //ConnectToDB establishes a connection to the database.
String sql = "INSERT INTO \"TableName\"" +
        "(\"Column1\", \"Column2\",\"Column3\",\"Column4\")" +
        "VALUES ('value1',value2, 'value3', 'value4') RETURNING 
         \"TableName\".\"TableId\"";
PreparedStatement prpState = conn.prepareStatement(sql);
ResultSet rs = prpState.executeQuery();
if(rs.next()){
      System.out.println(rs.getInt(1));
        }

Si está utilizando Statement , vaya a lo siguiente

//MY_NUMBER is the column name in the database 
String generatedColumns[] = {"MY_NUMBER"};
Statement stmt = conn.createStatement();

//String sql holds the insert query
stmt.executeUpdate(sql, generatedColumns);

ResultSet rs = stmt.getGeneratedKeys();

// The generated id

if(rs.next())
long key = rs.getLong(1);

Si está utilizando PreparedStatement , vaya a lo siguiente

String generatedColumns[] = {"MY_NUMBER"};
PreparedStatement pstmt = conn.prepareStatement(sql,generatedColumns);
pstmt.setString(1, "qwerty");

pstmt.execute();
ResultSet rs = pstmt.getGeneratedKeys();
if(rs.next())
long key = rs.getLong(1);

Utilice secuencias en postgres para las columnas de identificación:

INSERT mytable(myid) VALUES (nextval('MySequence'));

SELECT currval('MySequence');

currval devolverá el valor actual de la secuencia en la misma sesión.

(En MS SQL, usaría @@ identity o SCOPE_IDENTITY ())

PreparedStatement stmt = getConnection(PROJECTDB + 2)
    .prepareStatement("INSERT INTO fonts (font_size) VALUES(?) RETURNING fonts.*");
stmt.setString(1, "986");
ResultSet res = stmt.executeQuery();
while (res.next()) {
    System.out.println("Generated key: " + res.getLong(1));
    System.out.println("Generated key: " + res.getInt(2));
    System.out.println("Generated key: " + res.getInt(3));
}
stmt.close();

No use SELECT currval ('MySequence'): el valor se incrementa en las inserciones que fallan.

Para MyBatis 3.0.4 con Annotations y Postgresql driver 9.0-801.jdbc4, defina un método de interfaz en su Asignador como

public interface ObjectiveMapper {

@Select("insert into objectives" +
        " (code,title,description) values" +
        " (#{code}, #{title}, #{description}) returning id")
int insert(Objective anObjective);

Tenga en cuenta que @Select se utiliza en lugar de @Insert.

por ejemplo:

 Connection conn = null;
            PreparedStatement sth = null;
            ResultSet rs =null;
            try {
                conn = delegate.getConnection();
                sth = conn.prepareStatement(INSERT_SQL);
                sth.setString(1, pais.getNombre());
                sth.executeUpdate();
                rs=sth.getGeneratedKeys();
                if(rs.next()){
                    Integer id = (Integer) rs.getInt(1);
                    pais.setId(id);
                }
            } 

con , Statement.RETURN_GENERATED_KEYS); " no encontrado.

Usa ese código simple:

// Do your insert code

myDataBase.execSQL("INSERT INTO TABLE_NAME (FIELD_NAME1,FIELD_NAME2,...)VALUES (VALUE1,VALUE2,...)");

// Use the sqlite function "last_insert_rowid"

Cursor last_id_inserted = yourBD.rawQuery("SELECT last_insert_rowid()", null);

// Retrieve data from cursor.

last_id_inserted.moveToFirst(); // Don't forget that!

ultimo_id = last_id_inserted.getLong(0);  // For Java, the result is returned on Long type  (64)

Si está en una transacción, puede usar SELECT lastval () después de una inserción para obtener la última identificación generada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top