【问题标题】:ResultSet looping less than number of rowsResultSet 循环少于行数
【发布时间】:2013-07-03 11:56:34
【问题描述】:

我有一个返回 50 行的 ResultSet。我需要有一个临时表,我可以在其中插入这 50 行,以便我可以对其执行查询。

没有其他选择,所以请不要建议使用子查询或其他东西。需要一个临时表。

所以我使用以下方法插入行,显然虽然我知道 ResultSet 包含 50 行,但它在 while 循环中仅循环 13 次,因此当我从该表中提取一些字段时,我没有所需的结果。

public void insertValues(Connection con, ResultSet rs) {

    StringBuffer insert_into_temp = new StringBuffer();

    try {
        ResultSetMetaData rsmd = rs.getMetaData();
        int colCount = rsmd.getColumnCount();


        insert_into_temp.append("INSERT INTO SESSION.RETURNED_TICKETS (");

        for (int i = 1; i <= colCount; i++) {
            insert_into_temp.append(rsmd.getColumnLabel(i)); 
            insert_into_temp.append(",");
        }

        insert_into_temp.deleteCharAt(insert_into_temp.length()-1);
        insert_into_temp.append(")");

        insert_into_temp.append("\nVALUES(");

        // number of place-holders for values
        for (int i = 0; i < colCount; i++) {
             insert_into_temp.append("?,");  
        }

        insert_into_temp.deleteCharAt(insert_into_temp.length()-1);
        insert_into_temp.append(")");

        while(rs.next()){
            PreparedStatement pstmt = con.prepareStatement(insert_into_temp.toString());

            pstmt.setInt(1, rs.getInt(Ticket.FLD_ID));
            pstmt.setString(2, rs.getString(Ticket.FLD_DESCRIPTION));
            pstmt.setInt(3, rs.getInt(Ticket.FLD_TICKETTYPE));
            pstmt.setString(4, rs.getString("STATE"));
            pstmt.setString(5, rs.getString("PRIORITY"));
            pstmt.setString(6, rs.getString("OWNER"));
            pstmt.setString(7, rs.getString("SUBMITTER"));
            pstmt.setString(8, rs.getString("TYPE"));
            pstmt.setString(9, rs.getString(Ticket.FLD_TITLE));
            pstmt.setString(10, rs.getString("PROJECT"));
            pstmt.setInt(11, rs.getInt("PROJID"));
            pstmt.setDouble(12, rs.getDouble("RELEASE"));
            pstmt.setTimestamp(13, rs.getTimestamp(Ticket.FLD_SUBMITDATE));
            pstmt.setInt(14, rs.getInt(Ticket.FLD_CUSTOMER));  
            pstmt.setInt(15, rs.getInt("ROW_NEXT")); 

            int success = pstmt.executeUpdate();

            if (success != 1) // if not successful
                throw new SQLException("Failed to insert values into temporary table for linked/unlinked tickets");

        }

    } catch (SQLException e){
        LogFile.logError("[Report.execute()] "+e.getMessage());
        LogFile.logError(insert_into_temp.toString());
    }
}

可能是什么问题?我无法弄清楚为什么会这样。 谢谢

【问题讨论】:

  • @Bernice..t 表示您需要临时表?
  • 您可以通过删除所有这些插入代码来缩小您的问题范围。只需从结果集中打印出来。
  • 是的,我正在插入临时表。但正是这个 while 循环只循环了 13 次,并且只插入了 13 行,所以我认为这是相关的代码。打印输出只是从 where id in statement 中选择
  • 在处理 SELECT 语句结果的循环内使用 INSERT 效率极低。整个循环可以用 single 语句替换为 insert into ... select ... 行,这将更加更有效率。
  • @beny23:即使使用批处理语句,最有效的方法是在没有任何循环的单个语句中执行此操作

标签: java sql resultset


【解决方案1】:

如果我正确理解问题,而不是像这样每次使用都执行查询,

con.setAutoCommit(false); while (rs.next()) { // your setting values on prepared statement code pstmt.addBatch(); } pstmt.executeBatch(); con.setAutoCommit(true);

【讨论】:

    【解决方案2】:

    这并不能回答您的问题,但它确实说明了如何避免为每次迭代创建准备好的语句。相反,您可以准备一次,然后在每次迭代中绑定不同的值。

    public void insertValues(Connection con, ResultSet rs) {
        try {
    
            StringBuffer insert_into_temp = new StringBuffer();
    
            ResultSetMetaData rsmd = rs.getMetaData();
            int colCount = rsmd.getColumnCount();
    
            insert_into_temp.append("INSERT INTO SESSION.RETURNED_TICKETS (");
    
            for (int i = 1; i <= colCount; i++) {
                insert_into_temp.append(rsmd.getColumnLabel(i)); 
                insert_into_temp.append(",");
            }
    
            insert_into_temp.deleteCharAt(insert_into_temp.length()-1);
            insert_into_temp.append(")");
    
            insert_into_temp.append("\nVALUES(");
    
            // number of place-holders for values
            for (int i = 0; i < colCount; i++) {
                 insert_into_temp.append("?,");  
            }
            insert_into_temp.deleteCharAt(insert_into_temp.length()-1);
            insert_into_temp.append(")");
    
            PreparedStatement pstmt = con.prepareStatement(insert_into_temp.toString());
    
            while (rs.next()) {
    
                pstmt.setInt(1, rs.getInt(Ticket.FLD_ID));
                pstmt.setString(2, rs.getString(Ticket.FLD_DESCRIPTION));
                pstmt.setInt(3, rs.getInt(Ticket.FLD_TICKETTYPE));
                pstmt.setString(4, rs.getString("STATE"));
                pstmt.setString(5, rs.getString("PRIORITY"));
                pstmt.setString(6, rs.getString("OWNER"));
                pstmt.setString(7, rs.getString("SUBMITTER"));
                pstmt.setString(8, rs.getString("TYPE"));
                pstmt.setString(9, rs.getString(Ticket.FLD_TITLE));
                pstmt.setString(10, rs.getString("PROJECT"));
                pstmt.setInt(11, rs.getInt("PROJID"));
                pstmt.setDouble(12, rs.getDouble("RELEASE"));
                pstmt.setTimestamp(13, rs.getTimestamp(Ticket.FLD_SUBMITDATE));
                pstmt.setInt(14, rs.getInt(Ticket.FLD_CUSTOMER));  
                pstmt.setInt(15, rs.getInt("ROW_NEXT")); 
    
                int success = pstmt.executeUpdate();
    
                if (success != 1) // if not successful
                    throw new SQLException("Failed to insert values into temporary table for linked/unlinked tickets");
    
            }
    
        } catch (SQLException e){
            LogFile.logError("[Report.execute()] "+e.getMessage());
            LogFile.logError(insert_into_temp.toString());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 2022-06-10
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 2018-02-04
      相关资源
      最近更新 更多