INSERT
Java에서 JDBC를 사용하여 데이터베이스 (내 경우에는 Microsoft SQL Server)의 레코드를 원합니다 . 동시에 삽입 ID를 얻고 싶습니다. JDBC API를 사용하여이를 달성하려면 어떻게해야합니까?
답변
자동 생성 키인 경우이를 사용할 수 있습니다 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는 어디에 있습니까 ?
답변
내가 사용 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();
}
}
답변
다음 자바 코드를 사용하여 새로운 삽입 ID를 얻을 수 있습니다.
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);
}
