Domanda

    

Questa domanda ha già una risposta qui:

    
            
  •              Come ottenere l'ID di inserimento in JDBC?                                      12 risposte                          
  •     
    

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.

È stato utile?

Soluzione

Con PostgreSQL puoi farlo tramite la parola chiave RETURNING:

PostgresSQL - RETURNING

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

Restituirà il valore di " anyfield " ;. & Quot; anyfield " può essere una sequenza o no.

Per usarlo con JDBC, fai:

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

Altri suggerimenti

Consulta i documenti API per java.sql.Statement .

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

Va ??qualcosa del genere:

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

Se stai usando JDBC 3.0, puoi ottenere il valore del PK non appena lo hai 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);
}

Dalla versione del driver PostgreSQL JDBC 8.4-701 the PreparedStatement # getGeneratedKeys () è finalmente perfettamente funzionante. Lo usiamo qui quasi un anno di produzione per la nostra piena soddisfazione.

In "semplice JDBC" PreparedStatement deve essere creato come segue per renderlo in grado di restituire le chiavi:

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

Puoi scaricare la versione corrente del driver JDBC qui (che al momento è ancora 8,4-701).

Le sequenze in postgresql sono sicure per le transazioni. Quindi puoi usare

currval(sequence)

Citazione:

  

currval

     
    

Restituisce il valore ottenuto più recentemente da nextval per questa sequenza     nella sessione corrente. (Un errore è     segnalato se nextval non è mai stato     ha chiesto questa sequenza in questo     sessione.) Notare che perché questo è     restituendo un valore locale di sessione, esso     dà una risposta prevedibile anche se     altre sessioni stanno eseguendo 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 si utilizza Statement , selezionare quanto segue

//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 si utilizza PreparedStatement , procedere come segue

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

Usa sequenze in postgres per 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 sugli inserti che falliscono.

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

Nota che @Select è usato al posto di @Insert.

ad esempio:

 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); " 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 sei in una transazione puoi usare SELECT lastval () dopo un inserimento per ottenere l'ultimo ID generato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top