如何从最后插入的行中获取值?

时间:2008-10-27 18:42:11

标签: java database postgresql jdbc

有没有办法从最后插入的行中获取值?

我正在插入一个PK将自动增加的行,我想得到这个PK。表中只保证PK唯一。

我正在使用带有JDBC和PostgreSQL的Java。

14 个答案:

答案 0 :(得分:53)

使用PostgreSQL,您可以通过RETURNING关键字来完成:

PostgresSQL - RETURNING

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

它将返回“anyfield”的值。 “anyfield”可能是一个序列或不是。

要与JDBC一起使用,请执行:

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

答案 1 :(得分:28)

请参阅java.sql.Statement的API文档。

基本上,当您致电executeUpdate()executeQuery()时,请使用Statement.RETURN_GENERATED_KEYS常量。然后,您可以调用getGeneratedKeys来获取该执行创建的所有行的自动生成的密钥。 (假设您的JDBC驱动程序提供它。)

它有点像这样:

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

答案 2 :(得分:16)

如果您正在使用JDBC 3.0,那么您可以在插入PK后立即获取PK的值。

这篇文章讨论了如何: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);
}

答案 3 :(得分:11)

由于PostgreSQL JDBC驱动程序版本8.4-701 PreparedStatement#getGeneratedKeys()终于完全正常运行。我们在这里使用它差不多一年就完全满意了。

在“普通JDBC”中,需要按如下方式创建PreparedStatement以使其返回密钥:

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

您可以下载当前的JDBC驱动程序版本here(目前仍为8.4-701)。

答案 4 :(得分:8)

postgresql中的序列是事务安全的。

所以你可以使用

currval(sequence)

Quote:

  

CURRVAL

     
    

返回此序列的nextval最近获得的值     在本届会议上。 (错误是     如果nextval从来没有报道过     在这里要求这个序列     会议。)请注意,因为这是     返回会话本地值,它     即使是,也给出了可预测的答案     其他会话正在执行nextval     同时

  

答案 5 :(得分:7)

以下是我根据这里的答案解决的问题:

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

答案 6 :(得分:4)

如果您使用的是Statement,请转到以下

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

如果您使用的是PreparedStatement,请转到以下

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

答案 7 :(得分:1)

在postgres中使用id列的序列:

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

SELECT currval('MySequence');

currval将在同一会话中返回序列的当前值。

(在MS SQL中,您将使用@@ identity或SCOPE_IDENTITY())

答案 8 :(得分:1)

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

答案 9 :(得分:0)

不要使用SELECT currval('MySequence') - 在失败的插入上增加值。

答案 10 :(得分:0)

对于带有Annotations和Postgresql驱动程序9.0-801.jdbc4的MyBatis 3.0.4,您可以在Mapper中定义一个接口方法,如

public interface ObjectiveMapper {

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

请注意,使用@Select代替@Insert。

答案 11 :(得分:0)

例如:

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

找不到,Statement.RETURN_GENERATED_KEYS);"

答案 12 :(得分:0)

使用这个简单的代码:

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

答案 13 :(得分:0)

如果您在交易中,可以在插入后使用SELECT lastval()来获取最后生成的ID。