Come recuperare l'ID auto incrementato usando slick/plainSQL?



scala jdbc (2)

Dipende dal database.

Per MS SQL è SCOPE_IDENTITY (), per mySQL è LAST_INSERT_ID (). Prova a cercare l'equivalente per il tuo DB se non è uno dei precedenti.

Aggiunto da cvogt :

Non esiste attualmente una funzionalità integrata per SQL semplice per questo e nessun modo per accedere all'istruzione jdbc sottostante quando si utilizza l'interpolazione sql"..." o StaticQuery , che consentirebbe di accedere a getGeneratedKeys . Probabilmente potresti patchare l' interpolatore SQL e StatementInvoker per permetterlo. Sono solo 150 LOC. Forse vale la pena dare un colpo e presentare un PR.

Tuttavia, è possibile utilizzare uno dei metodi di sessione di Slick come withPreparedInsertStatement , che withPreparedInsertStatement metodi di connessione jdbc con un'istruzione jdbc. Ho creato un PR per aggiungere documentazione su questo: https://github.com/slick/slick/pull/691

https://src-bin.com

Non esiste una soluzione nativa slick / plainSQL per recuperare l'ID auto incrementato dell'attuale INSERT?

userId è un campo incrementale automatico nella mia tabella mySQL.

sql"""
   INSERT INTO `table`(`email`) 
   OUTPUT INSERTED.userId 
   VALUES ("[email protected].de")
""".as[Int].firstOption

L'aiuto sarebbe molto apprezzato.

Ciao Oliver


Answer #1

Grazie cvogt per l'aiuto in questa discussione. Penso che sarebbe utile presentare un PR, in quanto è una funzionalità molto comune e utile che non dovrebbe mancare nelle query plainSQL di slick .

Infine, ho trovato un rimedio per sostituire la funzione nativa mancante come segue.

Nella stessa sessione risolvo due domande. Il primo è l'istruzione INSERT , la seconda è SELECT LAST_INSERT_ID() che restituisce il valore generato automaticamente più nuovo che è stato impostato per la colonna AUTO_INCREMENT (1) recentemente eseguito. Maggiori dettagli qui: Riferimento MySQL - LAST_INSERT_ID ()

Database.forDataSource(dataSource).withDynSession {
  sqlu"""INSERT INTO `users`(`email`) VALUES ("[email protected].de")
  """.firstOption match {
    case Some(num) if num == 1 => sql"SELECT LAST_INSERT_ID()".as[Long].firstOption()
    case None => None
  }
}

Questo funziona per me adesso. Se ci sono miglioramenti, non esitare a pubblicare la tua soluzione.





slick