使用PreparedStatement.RETURN_GENERATED_KEYS时的SQLException

时间:2012-02-09 20:33:51

标签: java sql-server jdbc prepared-statement

这是有问题的代码块:

String sq = "INSERT INTO survey (session_id, character_id, timestamp) VALUES (?,?,?)";
PreparedStatement sadd = conn.prepareStatement(sq, PreparedStatement.RETURN_GENERATED_KEYS);
sadd.setLong(1, sessionId);
sadd.setLong(2, character_id);
sadd.setString(3, dateTime);
int affectedrows = sadd.executeUpdate();

//get the ID
long resultId = 0;
ResultSet key = sadd.getGeneratedKeys();
if (key.next()) {
    resultId = key.getLong(1);
}

此查询在没有PreparedStatement.RETURN_GENERATED_KEYS选项的情况下工作正常,但是当我突然添加executeUpdate()时抛出异常:

  

com.microsoft.sqlserver.jdbc.SQLServerException:生成了一个用于更新的结果集。

如果我取出PreparedStatement.RETURN_GENERATED_KEYS,它再次正常工作。出于沮丧,我将executeUpdate()改为executeQuery()只是为了看看我是否能够获得密钥并得到一个异常,它无法获取密钥,因为必须首先执行该语句。

如何获取生成的密钥?我正在使用SQL Server 2008和最新的JDBC驱动程序。

3 个答案:

答案 0 :(得分:1)

对我来说看起来像是一个驱动程序错误。

您应该从这里尝试更新的4.0驱动程序 - > http://www.microsoft.com/download/en/details.aspx?id=11774

如果这不起作用,一个解决方法是创建一个'insert'存储过程并将生成的id作为存储过程输出参数返回。

答案 1 :(得分:0)

看起来像个错误。你能尝试一下这个丑陋的选择吗?

  String dateTimeS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm").format(dateTime);
  String sq = "INSERT INTO survey (session_id, character_id, timestamp) "
          + "VALUES (" + sessionId + ", " + character_id + ", '" + dateTimeS + "')";
  Statement sadd = conn.createStatement();
  int affectedrows = sadd.executeUpdate(sq, Statement.RETURN_GENERATED_KEYS);

答案 2 :(得分:0)

我和4.0& D有同样的问题。 4.1 JDBC驱动程序。一段时间后,自动编号表上的插入将给出"生成的结果集用于更新。"随意的。我使用连接池,不知怎的,驱动程序可以进入一个状态,其中executeUpdate与Statement.RETURN_GENERATED_KEYS不再起作用。我发现在这种状态下executeQuery可以解决问题,但在初始状态下,executeQuery不起作用。这引出了以下解决方法:

PreparedStatement psInsert = connection.prepareStatement("INSERT INTO XYZ (A,B,C) VALUES(?,?,?)", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = null;
try {
    psInsert.setString(1, "A");
    psInsert.setString(2, "B");
    psInsert.setString(3, "C");
    Savepoint savePoint = connection.setSavepoint();
    try {
        psInsert.executeUpdate();
        rs = psInsert.getGeneratedKeys();
    } catch (SQLServerException sqe)
    {
        if (!sqe.getMessage().equals("A result set was generated for update."))
            throw sqe;
        connection.rollback(savePoint);
        rs = psInsert.executeQuery();
    }
    rs.next();
    idField = rs.getInt(1);
} finally {
    if(rs != null)
        rs.close();
    psInsert.close();
}