有没有办法从最后插入的行中获取值?
我正在插入一个 PK 会自动增加的行,我想得到这个 PK。只有 PK 保证在表中是唯一的。
我将 Java 与 JDBC 和 PostgreSQL 一起使用。
有没有办法从最后插入的行中获取值?
我正在插入一个 PK 会自动增加的行,我想得到这个 PK。只有 PK 保证在表中是唯一的。
我将 Java 与 JDBC 和 PostgreSQL 一起使用。
使用 PostgreSQL,您可以通过 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);
请参阅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();
如果您使用的是 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);
}
自从 PostgreSQL JDBC 驱动程序版本8.4-701以来,PreparedStatement#getGeneratedKeys()
终于可以完全正常工作了。我们在生产中使用了将近一年,对此我们非常满意。
在“plain JDBC”中,PreparedStatement
需要按如下方式创建以使其返回键:
statement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);
您可以在此处下载当前的 JDBC 驱动程序版本(目前仍为 8.4-701)。
postgresql 中的序列是事务安全的。所以你可以使用
currval(sequence)
曲线
返回当前会话中此序列的 nextval 最近获得的值。(如果在此会话中从未为此序列调用过 nextval,则会报告错误。)请注意,由于这将返回会话本地值,因此即使其他会话同时执行 nextval,它也会给出可预测的答案。
根据此处的答案,这是我解决它的方法:
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));
}
如果您正在使用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);
在 postgres 中为 id 列使用序列:
INSERT mytable(myid) VALUES (nextval('MySequence'));
SELECT currval('MySequence');
currval 将返回同一会话中序列的当前值。
(在 MS SQL 中,您将使用 @@identity 或 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();
不要使用 SELECT currval('MySequence') - 该值会在插入失败时递增。
对于带有注释和 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。
例如:
连接 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);"
找到。
使用那个简单的代码:
// 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)
如果您处于事务中,则可以SELECT lastval()
在插入后使用以获取最后生成的 id。