Question

    

Cette question a déjà une réponse ici:

    
            
  •              Comment obtenir l'ID d'insertion dans JDBC?                                      12 réponses                          
  •     
    

Est-il possible d'obtenir une valeur à partir de la dernière ligne insérée?

Je suis en train d'insérer une ligne où la PK augmentera automatiquement et j'aimerais obtenir cette PK. Seule la PK est garantie d'être unique dans la table.

J'utilise Java avec JDBC et PostgreSQL.

Était-ce utile?

La solution

Avec PostgreSQL, vous pouvez le faire via le mot clé RETURNING:

PostgresSQL - RETOURNER

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

Il renverra la valeur de "anyfield". "anyfield" peut être une séquence ou non.

Pour l'utiliser avec JDBC, procédez comme suit:

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

Autres conseils

Voir les documents de l'API pour java.sql.Statement .

Lorsque vous appelez executeUpdate () ou executeQuery () , utilisez la constante Statement.RETURN_GENERATED_KEYS . Vous pouvez ensuite appeler getGeneratedKeys pour obtenir les clés générées automatiquement de toutes les lignes créées par cette exécution. (En supposant que votre pilote JDBC le fournisse.)

Cela va dans le sens de ceci:

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

Si vous utilisez JDBC 3.0, vous pouvez obtenir la valeur du PK dès que vous l’avez insérée.

Voici un article qui explique comment: https://www.ibm .com / developerworks / java / bibliothèque / 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);
}

Depuis la version du pilote JDBC de PostgreSQL, 8.4-701 , le PreparedStatement # getGeneratedKeys () est enfin entièrement fonctionnel. Nous l'utilisons ici depuis presque un an en production à notre entière satisfaction.

Dans "JDBC" " le PreparedStatement doit être créé comme suit pour pouvoir renvoyer les clés:

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

Vous pouvez télécharger la version actuelle du pilote JDBC ici (qui est actuellement disponible). 8,4-701).

Les séquences dans postgresql sont sécurisées pour les transactions. Donc, vous pouvez utiliser le

currval(sequence)

Citation:

  

currval

     
    

Renvoie la dernière valeur obtenue par nextval pour cette séquence.     dans la session en cours. (Une erreur est     signalé si nextval n'a jamais été     appelé pour cette séquence dans cette     session.) Notez que parce que c’est     retournant une valeur locale à la session,     donne une réponse prévisible même si     d'autres sessions exécutent nextval     pendant ce temps.

  

Voici comment je l'ai résolu, en fonction des réponses fournies ici:

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

Si vous utilisez Statement , optez pour ce qui suit

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

Si vous utilisez PreparedStatement , procédez comme suit

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

Utilisez les séquences dans postgres pour les colonnes id:

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

SELECT currval('MySequence');

currval renverra la valeur actuelle de la séquence dans la même session.

(Sous MS SQL, vous utiliseriez @@ identity ou 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();

N'utilisez pas SELECT currval ('MySequence') - la valeur est incrémentée sur les insertions qui échouent.

Pour MyBatis 3.0.4 avec Annotations et le pilote Postgresql 9.0-801.jdbc4, vous définissez une méthode d’interface dans votre mappeur, comme

.
public interface ObjectiveMapper {

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

Notez que @Select est utilisé à la place de @Insert.

par exemple:

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

avec , Statement.RETURN_GENERATED_KEYS); " non trouvé.

Utilisez ce code simple:

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

Si vous êtes dans une transaction, vous pouvez utiliser SELECT lastval () après une insertion pour obtenir le dernier identifiant généré.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top