ResultSet不包含新插入的行

时间:2013-06-05 17:30:52

标签: java jdbc

我正在使用Oracle数据库10g,java并尝试使用ResultSet插入新行。

我有ResultSet的对象,它在方向上是可更新的和不敏感的,这意味着你可以在任何方向上遍历。

当我使用moveToInsertRow,insertRow和setter方法在ResultSet中插入行时,该行将插入到数据库中,但在遍历ResultSet时,我无法查看新插入的行

任何人都可以帮助我。

我的代码是:

import java.sql.*;
import java.io.*;
import java.util.Date;
public class TestResultSet{

public static void main(String...args){
    try{
        Connection con = DriverManager.getConnection("jdbc:oracle:thin:@//localhost:1521/xe", "system", "admin");
        Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
        ResultSet rs = stmt.executeQuery("Select EnrNo, Name, Gender, DOB From Student");
        int i;
        while(rs.next()){
            for(i = 1; i < 5; i++)
                System.out.print(rs.getString(i) + ", ");
            System.out.println();
        }

        //Inserting New Row
        rs.moveToInsertRow();
        rs.updateLong(1, 117020365276L);
        rs.updateString(2, "Ashfaq");
        rs.updateInt(3, 1);
        Date d = new Date();
        rs.updateDate(4, new java.sql.Date(d.getYear(), d.getMonth(), d.getDay()));
        rs.insertRow();
        //New Row Insertion ends here

        rs.first(); //Moving to first row
        do{
            for(i = 1; i < 5; i++)  //Index starts from 1, not from 0
                System.out.print(rs.getString(i) + ", ");
            System.out.println();
        }while(rs.next());
    }
    catch(SQLException ex){ ex.printStackTrace(); }
    catch(Exception ex){ ex.printStackTrace(); }
}
}

/*
Student Table Schema
EnrNo Numeric(12) Primary Key
Name varchar2(25);
Gender Numeric(1);
DOB date
*/

4 个答案:

答案 0 :(得分:1)

问题是新行已添加到数据库中,未添加到从数据库中恢复的当前行。因此,为了识别新行,您必须对表进行另一次读取。它可能是 inneficient (因为它取决于行数和查询的复杂程度),但这就是它的工作原理。

知道这一点,你的代码应该是这样的:

ResultSet rs = stmt.executeQuery("Select EnrNo, Name, Gender, DOB From Student");
int i;
while(rs.next()) {
    for(i = 1; i < 5; i++)
        System.out.print(rs.getString(i) + ", ");
    System.out.println();
}
//Inserting New Row
rs.moveToInsertRow();
rs.updateLong(1, 117020365276L);
rs.updateString(2, "Ashfaq");
rs.updateInt(3, 1);
Date d = new Date();
rs.updateDate(4, new java.sql.Date(d.getYear(), d.getMonth(), d.getDay()));
rs.insertRow();
//New Row Insertion ends here

//Moving to first row of the current recovered resultset
//thus not working as expected
//rs.first();

//close the resultset
rs.close();
//retrieve the rows from database again
rs = stmt.executeQuery("Select EnrNo, Name, Gender, DOB From Student");
do{
    for(i = 1; i < 5; i++)  //Index starts from 1, not from 0
        System.out.print(rs.getString(i) + ", ");
    System.out.println();
} while(rs.next());

答案 1 :(得分:1)

我记得有第三方库支持您正在寻找的功能,它们非常昂贵。

一般来说,是的,你必须重新获取。但是,您可以聪明一点:您可以智能地将查询分区为仅提取几百行

  • e.g。通过使用两个表,一个用于生产数据,另一个用于新的 数据,有时合并它们(您可以使用内存表中的新数据,如果需要,您可以创建跨表视图,但不是必需的)
  • 您可以创建自动增量索引,并仅获取最新的行
  • 或者您可以在Oracle中使用ROWNUM,在SQL Server中使用SELECT TOP,在MySQL中使用LIMIT等。
  • 当然,您可以实现自定义数据库驱动程序: - )

一般情况下,如果您定期获取超过几百行,则可能出现问题,也许您应该重新考虑客户端界面和实现。

答案 2 :(得分:1)

ResultSet ResultSet并不意味着检测对底层数据库的更新(这里不敏感意味着什么)。如果您希望TYPE_SCROLL_SENSITIVE检测到更改,则应使用TYPE_SCROLL_INSENSITIVE

然而,由于更改通常发生在不同的事务中,我相信大多数数据库都无法提供TYPE_SCROLL_SENSITIVE,如果可以,那么它们可能只允许您查看所选行数据的更改,但是没有检测到其他(或删除)行。

如果您尝试使用ResultSet,则可能需要检查数据库是否实际支持该类型(例如,使用TYPE_SCROLL_SENSITIVE)。或者通过检查创建的{{1}}是否实际上是指定类型(如果不支持,JDBC规范允许驱动程序'降级'类型和/或并发)。

您可能还想检查特定数据库和驱动程序的DatabaseMetaData.supportsResultSetType(int)及相关方法。

答案 3 :(得分:0)

试试这个:

String query = "Select EnrNo, Name, Gender, DOB From Student";
try {
    conn = DriverManager.getConnection(DB_URL, USER, PASS); 
    // change this to reflect your specific situation
    stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery(query);

    while (rs.next()) {                
        String EnrNo = rs.getString("EnrNo");
        String name = rs.getString("Name");
        String gender = rs.getString("Gender");
        String date = rs.getString("DOB");
        System.out.println(EnrNo + "\t" + name + "\t" + gender + "\t" + date);
    }
} catch (SQLException e) {
    e.printStackTrace();
}

// make sure you add these as your class variables:
Connection conn = null;
Statement stmt = null;