Come ottenere un valore dall’ultima riga inserita?

C’è un modo per ottenere un valore dall’ultima riga inserita?

Sto inserendo una riga in cui il PK aumenterà automaticamente e vorrei ottenere questo PK. Solo il PK è garantito per essere unico nella tabella.

Sto usando Java con un JDBC e PostgreSQL.

Con PostgreSQL puoi farlo tramite la parola chiave RETURNING:

PostgresSQL – RITORNO

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

Restituirà il valore di “anyfield”. “anyfield” può essere una sequenza o no.

Per usarlo con JDBC, fai:

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

Vedi i documenti API per java.sql.Statement .

Fondamentalmente, quando chiamate executeUpdate() o executeQuery() , usate la costante Statement.RETURN_GENERATED_KEYS . È quindi ansible chiamare getGeneratedKeys per ottenere le chiavi generate automaticamente di tutte le righe create da tale esecuzione. (Supponendo che il tuo driver JDBC lo fornisca).

Va qualcosa sulla falsariga di questo:

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

Se si utilizza JDBC 3.0, è ansible ottenere il valore del PK non appena viene inserito.

Ecco un articolo che parla di come: 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); } 

Poiché la versione del driver JDBC PostgreSQL 8.4-701, il PreparedStatement#getGeneratedKeys() è finalmente completamente funzionante. Lo usiamo qui quasi un anno in produzione con nostra piena soddisfazione.

In “plain JDBC” è necessario creare PreparedStatement come segue per farlo restituire le chiavi:

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

È ansible scaricare qui la versione del driver JDBC corrente (che al momento è ancora 8.4-701).

Le sequenze di postgresql sono transazioni sicure. Quindi puoi usare il

 currval(sequence) 

Citazione:

currval

Restituisce il valore più recente ottenuto da nextval per questa sequenza nella sessione corrente. (Viene segnalato un errore se nextval non è mai stato chiamato per questa sequenza in questa sessione.) Si noti che poiché ciò restituisce un valore locale della sessione, fornisce una risposta prevedibile anche se altre sessioni eseguono nextval nel frattempo.

Ecco come l’ho risolto, in base alle risposte qui:

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

Se stai usando Statement , vai al seguente

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

Se stai usando PreparedStatement , vai al seguente

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

Utilizza le sequenze in postgres per le colonne id:

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

currval restituirà il valore corrente della sequenza nella stessa sessione.

(In MS SQL, useresti @@ 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(); 

Non usare SELECT currval (‘MySequence’) – il valore viene incrementato su inserimenti che non riescono.

Per MyBatis 3.0.4 con Annotations e Postgresql driver 9.0-801.jdbc4 definisci un metodo di interfaccia nel tuo Mapper come

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

Si noti che @Select viene utilizzato al posto di @Insert.

per esempio:

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

con ,Statement.RETURN_GENERATED_KEYS);" non trovato.

Usa quel semplice codice:

 // 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) 

Se si è in una transazione, è ansible utilizzare SELECT lastval() dopo un inserimento per ottenere l’ultimo ID generato.