ฉันต้องการINSERT
บันทึกในฐานข้อมูล (ซึ่งเป็น Microsoft SQL Server ในกรณีของฉัน) โดยใช้ JDBC ใน Java ในเวลาเดียวกันฉันต้องการได้รับรหัสการแทรก ฉันจะบรรลุสิ่งนี้ได้อย่างไรโดยใช้ JDBC API
ฉันต้องการINSERT
บันทึกในฐานข้อมูล (ซึ่งเป็น Microsoft SQL Server ในกรณีของฉัน) โดยใช้ JDBC ใน Java ในเวลาเดียวกันฉันต้องการได้รับรหัสการแทรก ฉันจะบรรลุสิ่งนี้ได้อย่างไรโดยใช้ JDBC API
คำตอบ:
หากเป็นรหัสที่สร้างขึ้นโดยอัตโนมัติคุณสามารถใช้รหัสStatement#getGeneratedKeys()
นี้ได้ คุณจำเป็นต้องเรียกมันว่าเมื่อวันที่เดียวกันเป็นหนึ่งที่ถูกนำมาใช้เป็นStatement
INSERT
คุณต้องสร้างคำสั่งก่อนโดยใช้Statement.RETURN_GENERATED_KEYS
เพื่อแจ้งไดรเวอร์ JDBC เพื่อส่งคืนคีย์
นี่คือตัวอย่างพื้นฐาน:
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.");
}
}
}
}
โปรดทราบว่าคุณขึ้นอยู่กับไดรเวอร์ JDBC ว่าทำงานได้หรือไม่ ปัจจุบันเวอร์ชันล่าสุดส่วนใหญ่จะใช้งานได้ แต่ถ้าฉันถูกต้องไดรเวอร์ Oracle JDBC ยังคงมีปัญหาอยู่บ้าง MySQL และ DB2 รองรับมันมานานแล้ว PostgreSQL เริ่มให้การสนับสนุนเมื่อไม่นานมานี้ ฉันไม่สามารถแสดงความคิดเห็นเกี่ยวกับ MSSQL เพราะฉันไม่เคยใช้มัน
สำหรับ Oracle คุณสามารถเรียกใช้CallableStatement
ด้วยRETURNING
clause หรือ a SELECT CURRVAL(sequencename)
(หรือไวยากรณ์ใด ๆ ที่ระบุเฉพาะ DB เพื่อทำเช่นนั้น) โดยตรงหลังจากINSERT
อยู่ในธุรกรรมเดียวกันเพื่อรับคีย์ที่สร้างขึ้นล่าสุด ดูคำตอบนี้ด้วย
สร้างคอลัมน์ที่สร้าง
String generatedColumns[] = { "ID" };
ส่งผ่านคอลัมน์ยีนนี้ไปยังคำสั่งของคุณ
PreparedStatement stmtInsert = conn.prepareStatement(insertSQL, generatedColumns);
ใช้ResultSet
วัตถุเพื่อดึงข้อมูล GeneratedKeys ใน Statement
ResultSet rs = stmtInsert.getGeneratedKeys();
if (rs.next()) {
long id = rs.getLong(1);
System.out.println("Inserted ID -" + id); // display inserted record
}
ฉันกำลังกดปุ่ม Microsoft SQL Server 2008 R2 จากแอปพลิเคชันที่ใช้ JDBC แบบเธรดเดียวและดึงกลับ ID ล่าสุดโดยไม่ต้องใช้คุณสมบัติ RETURN_GENERATED_KEYS หรือ PreparedStatement ใด ๆ ดูเหมือนสิ่งนี้:
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;
}
โพสต์บล็อกนี้แยกตัวเลือก "last ID" หลักของ SQL Server ออกเป็นสามทาง: http://msjawahar.wordpress.com/2008/01/25/how-to-find-the-last-identity-value-inserted-in-the -sql-server / - ยังไม่ต้องการอีกสอง
เมื่อพบข้อผิดพลาด 'คุณสมบัติที่ไม่รองรับ' ขณะใช้Statement.RETURN_GENERATED_KEYS
งานให้ลองทำดังนี้:
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();
}
BATCHID
รหัสที่สร้างขึ้นอัตโนมัติอยู่ที่ไหน
BATCHID
ฉันใช้SQLServer 2008 แต่ฉันมีข้อ จำกัด ในการพัฒนา: ฉันไม่สามารถใช้ไดรเวอร์ใหม่ได้ฉันต้องใช้ "com.microsoft.jdbc.sqlserver.SQLServerDriver" (ฉันไม่สามารถใช้ "com.microsoft.sqlserver.jdbc" .SQLServerDriver ")
นั่นเป็นเหตุผลที่วิธีแก้ปัญหาconn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
โยนjava.lang.AbstractMethodErrorให้ฉัน ในสถานการณ์นี้วิธีแก้ปัญหาที่เป็นไปได้ที่ฉันพบคือโซลูชันเก่าที่ Microsoft แนะนำ:
วิธีการรับ @@ การระบุค่าการใช้ 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)
{
}
}
}
วิธีนี้ใช้ได้ผลสำหรับฉัน!
ฉันหวังว่านี่จะช่วยได้!
แทนที่จะแสดงความคิดเห็นฉันแค่ต้องการตอบโพสต์
อินเตอร์เฟสjava.sql.PreparedStatement
columnIndexes «คุณสามารถใช้ฟังก์ชัน prepareStatement ที่ยอมรับคำสั่ง columnIndexes และ SQL โดยที่ columnIndexes อนุญาตให้ตั้งค่าสถานะคงที่คือ Statement.RETURN_GENERATED_KEYS 1หรือ Statement.NO_GENERATED_KEYS [2] คำสั่ง SQL ที่อาจมีหนึ่งหรือมากกว่า '?' IN ตัวยึดตำแหน่งพารามิเตอร์
ซินแท็กซ์«
Connection.prepareStatement(String sql, int autoGeneratedKeys)
Connection.prepareStatement(String sql, int[] columnIndexes)
ตัวอย่าง:
PreparedStatement pstmt =
conn.prepareStatement( insertSQL, Statement.RETURN_GENERATED_KEYS );
COLUMNNAMES « รายการออก COLUMNNAMES 'id', 'uniqueID', ...
ชอบ ในตารางเป้าหมายที่มีคีย์ที่สร้างขึ้นอัตโนมัติที่ควรส่งคืน ไดรเวอร์จะเพิกเฉยหากคำสั่ง SQL ไม่ใช่INSERT
คำสั่ง
ซินแท็กซ์«
Connection.prepareStatement(String sql, String[] columnNames)
ตัวอย่าง:
String columnNames[] = new String[] { "id" };
PreparedStatement pstmt = conn.prepareStatement( insertSQL, columnNames );
ตัวอย่างเต็มรูปแบบ:
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();
}
}
คุณสามารถใช้รหัส java ต่อไปนี้เพื่อรับรหัสที่ใส่ใหม่
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);
}
ด้วย NativeQuery ของ Hibernate คุณต้องส่งคืน ResultList แทน SingleResult เนื่องจาก Hibernate จะแก้ไขเคียวรีเนทีฟ
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id
ชอบ
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id LIMIT 1
หากคุณพยายามที่จะรับผลลัพธ์เดียวซึ่งทำให้ฐานข้อมูลส่วนใหญ่ (อย่างน้อย PostgreSQL) จะโยนข้อผิดพลาดทางไวยากรณ์ หลังจากนั้นคุณสามารถเรียกรหัสผลลัพธ์จากรายการ (ซึ่งมักจะมีหนึ่งรายการ)
มันเป็นไปได้ที่จะใช้กับของปกติStatement
เช่นกัน (ไม่ใช่แค่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.");
}
}
ในกรณีของฉัน ->
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);
}
หากคุณใช้ Spring JDBC คุณสามารถใช้คลาส GeneratedKeyHolder ของ Spring เพื่อรับ ID ที่ถูกแทรก
ดูคำตอบนี้ ... วิธีแทรก id โดยใช้ 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
วิธีการConnection
ไม่คาดหวังว่าจะมีพารามิเตอร์ใด ๆ 2. execute
วิธีการจากการStatement
คาดหวังของสตริงที่มีแบบสอบถาม 3. execute
เมธอดส่งคืน: true
ถ้าผลลัพธ์แรกเป็นResultSet
วัตถุ false
ถ้าเป็นการนับการปรับปรุงหรือไม่มีผลลัพธ์ 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); }