59

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

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

我将 Java 与 JDBC 和 PostgreSQL 一起使用。

4

14 回答 14

66

使用 PostgreSQL,您可以通过 RETURNING 关键字来实现:

PostgresSQL - 返回

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);
于 2008-10-27T20:13:00.907 回答
28

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

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

它是这样的:

Statement stmt = conn.createStatement();
stmt.execute(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet keyset = stmt.getGeneratedKeys();
于 2008-10-27T21:02:10.307 回答
16

如果您使用的是 JDBC 3.0,那么您可以在插入 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);
}
于 2008-10-27T22:18:33.650 回答
13

自从 PostgreSQL JDBC 驱动程序版本8.4-701以来,PreparedStatement#getGeneratedKeys()终于可以完全正常工作了。我们在生产中使用了将近一年,对此我们非常满意。

在“plain JDBC”中,PreparedStatement需要按如下方式创建以使其返回键:

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

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

于 2010-06-01T21:28:50.107 回答
8

postgresql 中的序列是事务安全的。所以你可以使用

currval(sequence)

引用:

曲线

返回当前会话中此序列的 nextval 最近获得的值。(如果在此会话中从未为此序列调用过 nextval,则会报告错误。)请注意,由于这将返回会话本地值,因此即使其他会话同时执行 nextval,它也会给出可预测的答案。

于 2008-10-27T18:44:59.447 回答
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));
        }
于 2008-10-28T11:32:48.240 回答
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);
于 2013-05-01T14:23:38.957 回答
1

在 postgres 中为 id 列使用序列:

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

SELECT currval('MySequence');

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

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

于 2008-10-27T18:47:33.997 回答
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();
于 2011-01-07T08:45:03.177 回答
0

不要使用 SELECT currval('MySequence') - 该值会在插入失败时递增。

于 2010-05-25T20:22:10.800 回答
0

对于带有注释和 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。

于 2011-04-16T20:28:25.833 回答
0

例如:

连接 conn = null;
            PreparedStatement sth = null;
            结果集 rs =null;
            尝试 {
                conn = delegate.getConnection();
                sth = conn.prepareStatement(INSERT_SQL);
                sth.setString(1, pais.getNombre());
                sth.executeUpdate();
                rs=sth.getGeneratedKeys();
                如果(rs.next()){
                    整数 id = (整数) rs.getInt(1);
                    pais.setId(id);
                }
            }

没有,Statement.RETURN_GENERATED_KEYS);"找到。

于 2011-05-31T02:59:10.570 回答
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)
于 2012-06-28T12:36:22.147 回答
0

如果您处于事务中,则可以SELECT lastval()在插入后使用以获取最后生成的 id。

于 2014-04-03T08:32:40.017 回答