如何在jdbc中获取insert id?

j0pj023g  于 2021-07-09  发布在  Java
关注(0)|答案(12)|浏览(293)

我想 INSERT 在java中使用jdbc的数据库(在我的例子中是microsoftsqlserver)中的记录。同时,我想获得insert id。如何使用jdbcapi实现这一点?

nwo49xxi

nwo49xxi1#

我使用的是SQLServer2008,但我有一个开发限制:我不能为它使用新的驱动程序,我必须使用“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)
        {
        }
    }
}

这个方法对我有效!
我希望这有帮助!

6tr1vspr

6tr1vspr2#

就我而言->

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);
}
jdgnovmf

jdgnovmf3#

Connection cn = DriverManager.getConnection("Host","user","pass");
Statement st = cn.createStatement("Ur Requet Sql");
int ret  = st.execute();
u4dcyp6a

u4dcyp6a4#

它可以用在正常情况下 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.");
  }
}
jdzmm42g

jdzmm42g5#

使用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)抛出语法错误。之后,您可以从列表(通常只包含一个项)中获取结果id。

1bqhqjot

1bqhqjot6#

使用时遇到“不支持的功能”错误时 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。

djp7away

djp7away7#

您可以使用以下java代码来获取新的插入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);
}
nnsrf1az

nnsrf1az8#

我不想发表评论,只想回帖。
接口java.sql.preparedstatement
列索引« 可以使用接受columnindexes和sql语句的preparestatement函数。其中columnindexes允许的常量标志是statement.return \u generated \u keys 1或statement.no \u generated \u keys[2],参数占位符中可能包含一个或多个“?”的sql语句。
语法«

Connection.prepareStatement(String sql, int autoGeneratedKeys)
Connection.prepareStatement(String sql, int[] columnIndexes)

例子:

PreparedStatement pstmt = 
    conn.prepareStatement( insertSQL, Statement.RETURN_GENERATED_KEYS );

列名« 列出列名,如 '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();
    }
}
wz8daaqr

wz8daaqr9#

如果您使用的是springjdbc,那么可以使用spring的generatedkeyholder类来获取插入的id。
看看这个答案。。。如何使用springjdbctemplate.update(stringsql,obj…args)获取插入的id

ybzsozfc

ybzsozfc10#

如果是自动生成的关键点,则可以使用 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驱动程序来判断它是否工作。目前,大多数最后的版本都可以工作,但如果我是正确的,oraclejdbc驱动程序仍然有点麻烦。mysql和db2已经支持它很久了。postgresql不久前就开始支持它了。我无法评论mssql,因为我从未使用过它。
对于oracle,可以调用 CallableStatement 用一个 RETURNING 子句或a SELECT CURRVAL(sequencename)INSERT 在同一事务中获取最后生成的密钥。另请参见此答案。

dz6r00yl

dz6r00yl11#

创建生成的列

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
}
oprakyz7

oprakyz712#

我正在从基于单线程jdbc的应用程序中访问microsoftsqlserver2008r2,并在不使用return\u-generated\u-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“last id”选项:http://msjawahar.wordpress.com/2008/01/25/how-to-find-the-last-identity-value-inserted-in-the-sql-server/ -我还不需要另外两个。

相关问题