10 ответов:
если это автоматически сгенерированный ключ, то вы можете использовать
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пункт илиSELECT CURRVAL(sequencename)(или любой другой синтаксис, специфичный для БД) непосредственно послеINSERTв одной транзакции, чтобы получить последний сгенерированный ключ. Смотрите также этот ответ.
Создать Созданный Столбец
String generatedColumns[] = { "ID" };передайте этот генетический столбец в ваше заявление
PreparedStatement stmtInsert = conn.prepareStatement(insertSQL, generatedColumns);использовать
ResultSetобъект для извлечения GeneratedKeys на Оператор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 и возвращаю последний идентификатор без использования свойства 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; }это сообщение в блоге красиво изолирует три основных параметра 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(); }где BRANCHID-это автоматически сгенерированный идентификатор
Я использую SQLServer 2008, но у меня есть ограничение развития: я не могу использовать новый драйвер для него, я должен использовать "com.Microsoft.интерфейс jdbc.от SQLServer.SQLServerDriver " (я не могу использовать "com.Microsoft.от SQLServer.интерфейс jdbc.SQLServerDriver").
вот почему решение
conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)бросил a java.ленг.AbstractMethodError для меня. В этой ситуации возможным решением, которое я нашел, является старое, предложенное Microsoft: как получить значение @ @ IDENTITY с помощью JDBCimport 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 разрешенные постоянные флаги-это оператор.RETURN_GENERATED_KEYS1 or Statement. NO_GENERATED_KEYS[2], SQL заявление, которое может содержать один или более '? В местозаполнителей.
синтаксис "
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(); } }
С помощью Hibernate NativeQuery вам нужно вернуть 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' s также (не только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); }
Connection cn = DriverManager.getConnection("Host","user","pass"); Statement st = cn.createStatement("Ur Requet Sql"); int ret = st.execute();
Comments