답변:
자동 생성 키인 경우이를 사용할 수 있습니다 Statement#getGeneratedKeys()
. Statement
에 사용되는 것과 동일하게 호출해야 합니다 INSERT
. 먼저 키를 리턴하도록 JDBC 드라이버에 알리는 데 사용하여 명령문을 작성 해야Statement.RETURN_GENERATED_KEYS
합니다.
기본 예는 다음과 같습니다.
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
with RETURNING
절 또는 SELECT CURRVAL(sequencename)
(또는 DB 특정 구문)을 호출 INSERT
하여 마지막으로 생성 된 키를 얻을 수 있습니다. 이 답변 도 참조하십시오 .
생성 된 열 생성
String generatedColumns[] = { "ID" };
이 생성 된 열을 진술에 전달하십시오.
PreparedStatement stmtInsert = conn.prepareStatement(insertSQL, generatedColumns);
ResultSet
Statement를 사용 하여 GeneratedKeys를 페치하기 위해 오브젝트 사용
ResultSet rs = stmtInsert.getGeneratedKeys();
if (rs.next()) {
long id = rs.getLong(1);
System.out.println("Inserted ID -" + id); // display inserted record
}
단일 스레드 JDBC 기반 응용 프로그램에서 Microsoft SQL Server 2008 R2를 사용하고 RETURN_GENERATED_KEYS 속성이나 PreparedStatement를 사용하지 않고 마지막 ID를 가져옵니다. 다음과 같이 보입니다.
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;
}
이 블로그 게시물은 다음 세 가지 주요 SQL Server "마지막 ID"옵션을 훌륭하게 분리합니다 . -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
자동 생성 된 ID는 어디에 있습니까 ?
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를 사용하여 @@ IDENTITY 값을 검색하는 방법
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 «columnIndexes 및 SQL 문을 허용하는 PrepareStatement 함수를 사용할 수 있습니다. 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 «다음 과 같은 columnName을 나열합니다 '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();
}
}
Hibernate의 NativeQuery를 사용하면, Hibernate가 네이티브 쿼리를 수정하기 때문에 SingleResult 대신 ResultList를 반환해야한다
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id
처럼
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id LIMIT 1
단일 결과를 얻으려고하면 대부분의 데이터베이스 (최소한 PostgreSQL)에서 구문 오류가 발생합니다. 나중에 목록에서 결과 ID를 가져올 수 있습니다 (일반적으로 정확히 하나의 항목을 포함 함).
정상에 그것을 사용할 수 있습니다 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를 사용하는 경우 Spring의 GeneratedKeyHolder 클래스를 사용하여 삽입 된 ID를 얻을 수 있습니다.
이 답변을 참조하십시오 ... Spring Jdbctemplate.update (String sql, obj ... args)를 사용하여 id를 삽입하는 방법
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.
.if (generatedKeys.next()) primkey = generatedKeys.getInt(1); }