tras - ¿Cómo recuperar el ID incrementado automáticamente usando slick/plainSQL?
recuperar el id autogenerado tras insert en java (2)
Depende de la base de datos.
Para MS SQL es SCOPE_IDENTITY (), para mySQL es LAST_INSERT_ID (). Intenta buscar equivalente para tu DB si no es ninguno de los anteriores.
Agregado por cvogt :
Actualmente no existe una característica incorporada para SQL sencillo para esto y no hay forma de acceder a la declaración jdbc subyacente al usar la interpolación sql"..."
StaticQuery
o StaticQuery
, lo que le permitiría acceder a getGeneratedKeys
. Probablemente puedas parchar el interpolador SQL y StatementInvoker para permitir esto. Son solo 150 LOC. Tal vez vale la pena dar una oportunidad y enviar un PR.
Sin embargo, puede usar uno de los métodos de sesión Slick como withPreparedInsertStatement
, que envuelve los métodos de conexión de jdbc para que funcionen con una instrucción jdbc. Creé un RP para agregar documentación sobre esto: https://github.com/slick/slick/pull/691
¿No hay una solución slick / plainSQL nativa para recuperar el ID autoincrementado del INSERT actual?
userId es un campo incremental automático en mi tabla mySQL.
sql"""
INSERT INTO `table`(`email`)
OUTPUT INSERTED.userId
VALUES ("[email protected]")
""".as[Int].firstOption
La ayuda sería muy apreciada.
Saludos Oliver
Gracias cvogt por ayudar en esta discusión. Creo que sería útil enviar un PR, ya que es una funcionalidad muy común y útil que no debería faltar en las consultas plainSQL de slick .
Finalmente, encontré una solución alternativa para reemplazar la función nativa faltante de la siguiente manera.
Dentro de la misma sesión resuelvo dos consultas. La primera es la INSERT
, la segunda instrucción es SELECT LAST_INSERT_ID()
que devuelve el valor más reciente generado automáticamente que se estableció para la columna AUTO_INCREMENT
por INSERT
(1) recientemente ejecutado. Más detalles aquí: Referencia de MySQL - LAST_INSERT_ID ()
Database.forDataSource(dataSource).withDynSession {
sqlu"""INSERT INTO `users`(`email`) VALUES ("[email protected]")
""".firstOption match {
case Some(num) if num == 1 => sql"SELECT LAST_INSERT_ID()".as[Long].firstOption()
case None => None
}
}
Esto funciona para mí ahora mismo. Si hay alguna mejora, no dude en publicar su solución.