【问题标题】:Get RETURNING value from Postgresql via Java通过 Java 从 Postgresql 获取返回值
【发布时间】:2014-07-04 16:42:34
【问题描述】:

从 Java 中,我在 Postgresql 中调用了一个准备好的语句,其中插入了一个我的身份列的 RETURNING 子句。在 PG admin 中它会立即返回,但不知道如何从我准备好的语句中获取它:

        String insertStatement = "INSERT INTO person(\n" +
                "            name, address, phone, customer_type, \n" +
                "            start_dtm)\n" +
                "    VALUES (?, ?, ?, ?, \n" +
                "            ?)\n" +
                "    RETURNING person_id;";


        PreparedStatement stmt = connection.prepareStatement(insertStatement);

        stmt.setObject(1, perToSave.getName(null));
        stmt.setObject(2, editToSave.getAddress());
        stmt.setObject(3, editToSave.getPhone());
        stmt.setObject(4, editToSave.getCustType());
        long epochTime = java.lang.System.currentTimeMillis();
        stmt.setObject(5, new java.sql.Date(epochTime));

        stmt.executeUpdate();

【问题讨论】:

    标签: java prepared-statement


    【解决方案1】:

    根据javadoc,PreparedStatement 继承自Statement,后者包含一个getResultSet() 方法。换句话说,试试这个:

    String insertStatement = "INSERT INTO person(\n" +
                    "            name, address, phone, customer_type, \n" +
                    "            start_dtm)\n" +
                    "    VALUES (?, ?, ?, ?, \n" +
                    "            ?)\n" +
                    "    RETURNING person_id;";
    
    
    PreparedStatement stmt = connection.prepareStatement(insertStatement);
    
    stmt.setObject(1, perToSave.getName(null));
    stmt.setObject(2, editToSave.getAddress());
    stmt.setObject(3, editToSave.getPhone());
    stmt.setObject(4, editToSave.getCustType());
    long epochTime = java.lang.System.currentTimeMillis();
    stmt.setObject(5, new java.sql.Date(epochTime));
    
    stmt.execute();
    ResultSet last_updated_person = stmt.getResultSet();
    last_updated_person.next();
    int last_updated_person_id = last_updated_person.getInt(1);
    

    如果您还有其他问题,请发表评论。

    【讨论】:

    • executeUpdate() 抛出“org.postgresql.util.PSQLException: A result was returned when none is expected.” 因为它不应该看到返回的结果。也 getresultSet() 没有下一个调用 throughs :org.postgresql.util.PSQLException: ResultSet 没有正确定位,也许你需要调用下一个。
    • 此答案使用“executeUpdate”,但正确的调用方法是“execute”,如高度赞成但未接受的答案所示。从下一个答案复制并粘贴:-)
    • 这不是一个正确的答案。正确的赞成但错误地未被接受的答案如下
    【解决方案2】:

    JDBC 内置支持返回插入语句的主键值。从 SQL 中删除“returning”子句并指定 PreparedStatement.RETURN_GENERATED_KEYS 作为 prepareStatment(...) 调用的第二个参数。然后,您可以在调用 executeUpdate() 后在 PreparedStatement 对象上调用 stmt.getGeneratedKeys() 来获取生成的主键。

    String insertStatement = "INSERT INTO person(\n" +
        "            name, address, phone, customer_type, \n" +
        "            start_dtm)\n" +
        "    VALUES (?, ?, ?, ?, \n" +
        "            ?)";
    
    PreparedStatement stmt = connection.prepareStatement(insertStatement,
        PreparedStatement.RETURN_GENERATED_KEYS);
    
    stmt.setObject(1, perToSave.getName(null));
    stmt.setObject(2, editToSave.getAddress());
    stmt.setObject(3, editToSave.getPhone());
    stmt.setObject(4, editToSave.getCustType());
    long epochTime = java.lang.System.currentTimeMillis();
    stmt.setObject(5, new java.sql.Date(epochTime));
    
    stmt.executeUpdate();
        
    ResultSet resultSet = stmt.getGeneratedKeys();
    resultSet.next();
    int lastInsertedPersonID = resultSet.getInt(1);
    

    【讨论】:

      【解决方案3】:

      我没有足够的声誉来发表评论,我的编辑被拒绝了,很抱歉重新发布来自 hd1 的已接受答案。

      executeUpdate 不期望返回;使用执行。 在尝试检索值之前检查是否有一些结果。

      String insertStatement = "INSERT INTO person(\n" +
                      "            name, address, phone, customer_type, \n" +
                      "            start_dtm)\n" +
                      "    VALUES (?, ?, ?, ?, \n" +
                      "            ?)\n" +
                      "    RETURNING person_id;";
      
      PreparedStatement stmt = connection.prepareStatement(insertStatement);
      
      stmt.setObject(1, perToSave.getName(null));
      stmt.setObject(2, editToSave.getAddress());
      stmt.setObject(3, editToSave.getPhone());
      stmt.setObject(4, editToSave.getCustType());
      long epochTime = java.lang.System.currentTimeMillis();
      stmt.setObject(5, new java.sql.Date(epochTime));
      
      stmt.execute();
      ResultSet last_updated_person = stmt.getResultSet();
      if(last_updated_person.next()) {
         int last_updated_person_id = last_updated_person.getInt(1);
      }
      

      【讨论】:

      • 发布您自己的答案来完成另一个用户的答案是可以的,只要您提供信用(您已经这样做了) - 请参阅meta.stackoverflow.com/a/338292/5375403 虽然如果您清楚地说明您的答案有何不同,这将是一个好主意从原始版本,以及为什么这样做。
      【解决方案4】:

      调用executeUpdate() 不希望语句产生任何结果。调用 stmt.execute() 然后调用 stmt.getResultSet()

      【讨论】:

        猜你喜欢
        • 2016-03-13
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 2012-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多