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

Resuelto Satya asked hace 14 años • 15 respuestas

Quiero INSERTun registro en una base de datos (que en mi caso es Microsoft SQL Server) usando JDBC en Java. Al mismo tiempo, quiero obtener el ID de inserción. ¿Cómo puedo lograr esto usando la API JDBC?

Satya avatar Dec 16 '09 21:12 Satya
Aceptado

Si es una clave generada automáticamente, puede usarla Statement#getGeneratedKeys()para esto. Debe llamarlo de la misma manera Statementque el que se utiliza para INSERT. Primero debe crear la declaración usando Statement.RETURN_GENERATED_KEYSpara notificar al controlador JDBC que devuelva las claves.

Aquí hay un ejemplo básico:

public void create(User user) throws SQLException {
    try (
        Connection connection = dataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement(SQL_INSERT,
                                      Statement.RETURN_GENERATED_KEYS);
    ) {
        statement.setString(1, user.getName());
        statement.setString(2, user.getPassword());
        statement.setString(3, user.getEmail());
        // ...

        int affectedRows = statement.executeUpdate();

        if (affectedRows == 0) {
            throw new SQLException("Creating user failed, no rows affected.");
        }

        try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
            if (generatedKeys.next()) {
                user.setId(generatedKeys.getLong(1));
            }
            else {
                throw new SQLException("Creating user failed, no ID obtained.");
            }
        }
    }
}

Tenga en cuenta que depende del controlador JDBC para que funcione. Actualmente, la mayoría de las últimas versiones funcionan, pero si no me equivoco, el controlador JDBC de Oracle sigue siendo algo problemático con esto. MySQL y DB2 ya lo soportaron durante mucho tiempo. PostgreSQL comenzó a admitirlo no hace mucho. No puedo comentar sobre MSSQL porque nunca lo he usado.

Para Oracle, puede invocar a CallableStatementcon una RETURNINGcláusula o a SELECT CURRVAL(sequencename)(o cualquier sintaxis específica de la base de datos para hacerlo) directamente después de INSERTen la misma transacción para obtener la última clave generada. Vea también esta respuesta .

BalusC avatar Dec 16 '2009 15:12 BalusC
  1. Crear columna generada

    String generatedColumns[] = { "ID" };
    
  2. Pase esta columna generada a su estado de cuenta

    PreparedStatement stmtInsert = conn.prepareStatement(insertSQL, generatedColumns);
    
  3. Utilice ResultSetun objeto para recuperar las claves generadas en la declaración

    ResultSet rs = stmtInsert.getGeneratedKeys();
    
    if (rs.next()) {
        long id = rs.getLong(1);
        System.out.println("Inserted ID -" + id); // display inserted record
    }
    
Harsh Maheswari avatar Dec 06 '2016 04:12 Harsh Maheswari

Cuando encuentre un error de "Función no compatible" mientras usa Statement.RETURN_GENERATED_KEYS, intente esto:

String[] returnId = { "BATCHID" };
String sql = "INSERT INTO BATCH (BATCHNAME) VALUES ('aaaaaaa')";
PreparedStatement statement = connection.prepareStatement(sql, returnId);
int affectedRows = statement.executeUpdate();

if (affectedRows == 0) {
    throw new SQLException("Creating user failed, no rows affected.");
}

try (ResultSet rs = statement.getGeneratedKeys()) {
    if (rs.next()) {
        System.out.println(rs.getInt(1));
    }
    rs.close();
}

¿ Dónde BATCHIDestá la identificación generada automáticamente?

Eitan Rimon avatar Dec 14 '2015 08:12 Eitan Rimon