Jawaban:
Jika ini adalah kunci yang dibuat secara otomatis, maka Anda dapat menggunakannya Statement#getGeneratedKeys()
untuk ini. Anda harus menyebutnya sama Statement
dengan yang digunakan untuk INSERT
. Anda harus terlebih dahulu membuat pernyataan menggunakan Statement.RETURN_GENERATED_KEYS
untuk memberi tahu driver JDBC untuk mengembalikan kunci.
Inilah contoh dasar:
public void create(User user) throws SQLException {
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_INSERT,
Statement.RETURN_GENERATED_KEYS);
) {
statement.setString(1, user.getName());
statement.setString(2, user.getPassword());
statement.setString(3, user.getEmail());
// ...
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating user failed, no rows affected.");
}
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
user.setId(generatedKeys.getLong(1));
}
else {
throw new SQLException("Creating user failed, no ID obtained.");
}
}
}
}
Perhatikan bahwa Anda bergantung pada driver JDBC, apakah itu berfungsi. Saat ini, sebagian besar versi terakhir akan berfungsi, tetapi jika saya benar, driver Oracle JDBC masih agak bermasalah dengan ini. MySQL dan DB2 sudah mendukungnya sejak lama. PostgreSQL mulai mendukungnya belum lama ini. Saya tidak dapat berkomentar tentang MSSQL karena saya belum pernah menggunakannya.
Untuk Oracle, Anda dapat memanggil CallableStatement
dengan RETURNING
klausa atau SELECT CURRVAL(sequencename)
(atau sintaks khusus DB apa pun untuk melakukannya) langsung setelah INSERT
dalam transaksi yang sama untuk mendapatkan kunci yang dihasilkan terakhir. Lihat juga jawaban ini .
generatedKeys.next()
pengembalian true
jika DB kembali kunci yang dihasilkan. Lihat, ini a ResultSet
. The close()
hanya untuk sumber informasi gratis. Kalau tidak, DB Anda akan habis dalam jangka panjang dan aplikasi Anda akan rusak. Anda hanya perlu menulis sendiri beberapa metode utilitas yang melakukan tugas penutup. Lihat juga ini dan jawaban ini .
Buat Kolom Yang Dihasilkan
String generatedColumns[] = { "ID" };
Berikan Kolom yang dibuat ini ke pernyataan Anda
PreparedStatement stmtInsert = conn.prepareStatement(insertSQL, generatedColumns);
Gunakan ResultSet
objek untuk mengambil GeneratedKeys pada Pernyataan
ResultSet rs = stmtInsert.getGeneratedKeys();
if (rs.next()) {
long id = rs.getLong(1);
System.out.println("Inserted ID -" + id); // display inserted record
}
Saya memukul Microsoft SQL Server 2008 R2 dari aplikasi berbasis JDBC single-threaded dan menarik kembali ID terakhir tanpa menggunakan properti RETURN_GENERATED_KEYS atau PreparedStatement. Terlihat seperti ini:
private int insertQueryReturnInt(String SQLQy) {
ResultSet generatedKeys = null;
int generatedKey = -1;
try {
Statement statement = conn.createStatement();
statement.execute(SQLQy);
} catch (Exception e) {
errorDescription = "Failed to insert SQL query: " + SQLQy + "( " + e.toString() + ")";
return -1;
}
try {
generatedKey = Integer.parseInt(readOneValue("SELECT @@IDENTITY"));
} catch (Exception e) {
errorDescription = "Failed to get ID of just-inserted SQL query: " + SQLQy + "( " + e.toString() + ")";
return -1;
}
return generatedKey;
}
Posting blog ini dengan baik mengisolasi tiga opsi SQL Server "ID terakhir": http://msjawahar.wordpress.com/2008/01/25/how-to-find-the-Last-identity-value-inserted-in-the -sql-server / - belum membutuhkan dua lainnya.
Saat menemukan kesalahan 'Fitur yang tidak didukung' saat menggunakan Statement.RETURN_GENERATED_KEYS
, coba ini:
String[] returnId = { "BATCHID" };
String sql = "INSERT INTO BATCH (BATCHNAME) VALUES ('aaaaaaa')";
PreparedStatement statement = connection.prepareStatement(sql, returnId);
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating user failed, no rows affected.");
}
try (ResultSet rs = statement.getGeneratedKeys()) {
if (rs.next()) {
System.out.println(rs.getInt(1));
}
rs.close();
}
Di mana BATCHID
id yang dibuat secara otomatis.
BATCHID
Saya menggunakan SQLServer 2008, tetapi saya memiliki batasan pengembangan: Saya tidak dapat menggunakan driver baru untuk itu, saya harus menggunakan "com.microsoft.jdbc.sqlserver.SQLServerDriver" (saya tidak bisa menggunakan "com.microsoft.sqlserver.jdbc .SQLServerDriver ").
Karena itulah solusinya conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
melemparkan java.lang.AbstractMethodError untuk saya. Dalam situasi ini, solusi yang mungkin saya temukan adalah yang lama yang disarankan oleh Microsoft:
Cara Mengambil Nilai @@ IDENTITY Menggunakan JDBC
import java.sql.*;
import java.io.*;
public class IdentitySample
{
public static void main(String args[])
{
try
{
String URL = "jdbc:microsoft:sqlserver://yourServer:1433;databasename=pubs";
String userName = "yourUser";
String password = "yourPassword";
System.out.println( "Trying to connect to: " + URL);
//Register JDBC Driver
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
//Connect to SQL Server
Connection con = null;
con = DriverManager.getConnection(URL,userName,password);
System.out.println("Successfully connected to server");
//Create statement and Execute using either a stored procecure or batch statement
CallableStatement callstmt = null;
callstmt = con.prepareCall("INSERT INTO myIdentTable (col2) VALUES (?);SELECT @@IDENTITY");
callstmt.setString(1, "testInputBatch");
System.out.println("Batch statement successfully executed");
callstmt.execute();
int iUpdCount = callstmt.getUpdateCount();
boolean bMoreResults = true;
ResultSet rs = null;
int myIdentVal = -1; //to store the @@IDENTITY
//While there are still more results or update counts
//available, continue processing resultsets
while (bMoreResults || iUpdCount!=-1)
{
//NOTE: in order for output parameters to be available,
//all resultsets must be processed
rs = callstmt.getResultSet();
//if rs is not null, we know we can get the results from the SELECT @@IDENTITY
if (rs != null)
{
rs.next();
myIdentVal = rs.getInt(1);
}
//Do something with the results here (not shown)
//get the next resultset, if there is one
//this call also implicitly closes the previously obtained ResultSet
bMoreResults = callstmt.getMoreResults();
iUpdCount = callstmt.getUpdateCount();
}
System.out.println( "@@IDENTITY is: " + myIdentVal);
//Close statement and connection
callstmt.close();
con.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
try
{
System.out.println("Press any key to quit...");
System.in.read();
}
catch (Exception e)
{
}
}
}
Solusi ini berhasil untuk saya!
Saya harap ini membantu!
Alih-alih komentar , saya hanya ingin menjawab posting.
Antarmuka java.sql.PreparedStatement
columnIndexes «Anda dapat menggunakan fungsi prepStatement yang menerima pernyataan columnIndexes dan SQL. Di mana kolomIndeks diizinkan bendera konstan adalah Statement.RETURN_GENERATED_KEYS 1 atau Statement.NO_GENERATED_KEYS [2], pernyataan SQL yang mungkin mengandung satu atau lebih '?' IN placeholder parameter.
SINTETIS «
Connection.prepareStatement(String sql, int autoGeneratedKeys)
Connection.prepareStatement(String sql, int[] columnIndexes)
Contoh:
PreparedStatement pstmt =
conn.prepareStatement( insertSQL, Statement.RETURN_GENERATED_KEYS );
Nama Kolom « Sebutkan Nama Kolom seperti 'id', 'uniqueID', ...
. di tabel target yang berisi kunci yang dibuat secara otomatis yang harus dikembalikan. Pengemudi akan mengabaikannya jika pernyataan SQL bukan INSERT
pernyataan.
SINTETIS «
Connection.prepareStatement(String sql, String[] columnNames)
Contoh:
String columnNames[] = new String[] { "id" };
PreparedStatement pstmt = conn.prepareStatement( insertSQL, columnNames );
Contoh Lengkap:
public static void insertAutoIncrement_SQL(String UserName, String Language, String Message) {
String DB_URL = "jdbc:mysql://localhost:3306/test", DB_User = "root", DB_Password = "";
String insertSQL = "INSERT INTO `unicodeinfo`( `UserName`, `Language`, `Message`) VALUES (?,?,?)";
//"INSERT INTO `unicodeinfo`(`id`, `UserName`, `Language`, `Message`) VALUES (?,?,?,?)";
int primkey = 0 ;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection(DB_URL, DB_User, DB_Password);
String columnNames[] = new String[] { "id" };
PreparedStatement pstmt = conn.prepareStatement( insertSQL, columnNames );
pstmt.setString(1, UserName );
pstmt.setString(2, Language );
pstmt.setString(3, Message );
if (pstmt.executeUpdate() > 0) {
// Retrieves any auto-generated keys created as a result of executing this Statement object
java.sql.ResultSet generatedKeys = pstmt.getGeneratedKeys();
if ( generatedKeys.next() ) {
primkey = generatedKeys.getInt(1);
}
}
System.out.println("Record updated with id = "+primkey);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
Anda dapat menggunakan kode java berikut untuk mendapatkan id yang dimasukkan baru.
ps = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, quizid);
ps.setInt(2, userid);
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
lastInsertId = rs.getInt(1);
}
Dengan NativeQuery Hibernate, Anda harus mengembalikan ResultList alih-alih SingleResult, karena Hibernate memodifikasi kueri asli
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id
Suka
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id LIMIT 1
jika Anda mencoba untuk mendapatkan hasil tunggal, yang menyebabkan sebagian besar basis data (setidaknya PostgreSQL) melempar kesalahan sintaksis. Setelah itu, Anda dapat mengambil id yang dihasilkan dari daftar (yang biasanya berisi tepat satu item).
Dimungkinkan untuk menggunakannya dengan normal Statement
juga (bukan hanya PreparedStatement
)
Statement statement = conn.createStatement();
int updateCount = statement.executeUpdate("insert into x...)", Statement.RETURN_GENERATED_KEYS);
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
return generatedKeys.getLong(1);
}
else {
throw new SQLException("Creating failed, no ID obtained.");
}
}
Dalam kasus saya ->
ConnectionClass objConnectionClass=new ConnectionClass();
con=objConnectionClass.getDataBaseConnection();
pstmtGetAdd=con.prepareStatement(SQL_INSERT_ADDRESS_QUERY,Statement.RETURN_GENERATED_KEYS);
pstmtGetAdd.setString(1, objRegisterVO.getAddress());
pstmtGetAdd.setInt(2, Integer.parseInt(objRegisterVO.getCityId()));
int addId=pstmtGetAdd.executeUpdate();
if(addId>0)
{
ResultSet rsVal=pstmtGetAdd.getGeneratedKeys();
rsVal.next();
addId=rsVal.getInt(1);
}
Jika Anda menggunakan Spring JDBC, Anda bisa menggunakan kelas GeneratedKeyHolder Spring untuk mendapatkan ID yang dimasukkan.
Lihat jawaban ini ... Bagaimana cara memasukkan id menggunakan Spring Jdbctemplate.update (String sql, obj ... args)
Connection cn = DriverManager.getConnection("Host","user","pass");
Statement st = cn.createStatement("Ur Requet Sql");
int ret = st.execute();
createStatement
Metode dari Connection
jangan mengharapkan params. 2. execute
Metode dari Statement
mengharapkan String dengan Kueri. 3. execute
Metode mengembalikan: true
jika hasil pertama adalah ResultSet
objek; false
apakah itu jumlah pembaruan atau tidak ada hasil. docs.oracle.com/javase/7/docs/api/java/sql/…
String sql = "INSERT INTO 'yash'.'mytable' ('name') VALUES (?)"; int primkey = 0 ; PreparedStatement pstmt = con.prepareStatement(sql, new String[] { "id" }/*Statement.RETURN_GENERATED_KEYS*/); pstmt.setString(1, name); if (pstmt.executeUpdate() > 0) { java.sql.ResultSet generatedKeys = pstmt.
getGeneratedKeys ();if (generatedKeys.next()) primkey = generatedKeys.getInt(1); }