3

我一直在使用 JDBC 和不同类型的 ResultSet 并且有一个关于使其成为 TYPE_SCROLL_SENSITIVE 的问题(这个问题与敏感部分有关,而不是类型滚动部分)。理论上说,数据库中的变化反映在 ResultSet 中,反之亦然,但这对我来说并没有发生。

这是我尝试过的东西:

Connection conn = null;
try {
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
    String url = "jdbc:oracle:thin:@oracle.myCompany.com:1521:xe";
    conn = DriverManager.getConnection(url, "username", "password");
    Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

    String query = "SELECT user_id, first_name, last_name FROM Users";
    ResultSet rs = stmt.executeQuery(query);

    while(rs.next()){
        System.out.println("-----------------------------");
        System.out.println(rs.getInt(1));
        System.out.println(rs.getString("first_name"));
        System.out.println(rs.getString("last_name"));

        int id = rs.getInt(1);
        rs.updateInt(1,100+id);
    }

} catch (SQLException e) {
    e.printStackTrace();
} finally{
    conn.close();
}

当我更新 ID 并添加 100 时,更改不会显示在数据库中(如果在此下方,我添加 rs.updateRow() 那么它确实会更新数据库。但是如果我这样做也会更新数据库TYPE_SCROLL_INSENSITIVE)。

我尝试的另一件事是:

Connection conn = null;
try {
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
    String url = "jdbc:oracle:thin:@oracle.myCompany.com:1521:xe";
    conn = DriverManager.getConnection(url, "username", "password");
    Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

    String query = "SELECT user_id, first_name, last_name FROM Users";
    ResultSet rs = stmt.executeQuery(query);

    String query2 = "INSERT INTO User VALUES (4, 'Joe', 'Bloggs')";
    stmt.executeUpdate(query2);

    while(rs.next()){
        System.out.println("-----------------------------");
        System.out.println(rs.getInt(1));
        System.out.println(rs.getString("first_name"));
        System.out.println(rs.getString("last_name"));

        int id = rs.getInt(1);
        rs.updateInt(1,100+id);
    }

} catch (SQLException e) {
    e.printStackTrace();
} finally{
    conn.close();
}

但是,如果我运行这段代码,并期望新行在 resultSet 中,因为它很敏感......我在行上得到一个 NullPointerException :while(rs.next()){

那么有人可以解释一下敏感的 ResultSet 是如何工作的以及我做错了什么吗?可能举个例子?

4

3 回答 3

3

TYPE_SCROLL_SENSITIVE 表示如果在迭代数据时表发生更改,您将看到它。要重现此行为,请中断

System.out.println("-----------------------------");

使用外部工具更改 first_name,然后执行此行

System.out.println(rs.getString("first_name"));

更改应该是可见的。

请注意,此功能是可选的。要测试它是否已启用,请运行此

boolean res = conn.getMetaData().ownDeletesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE);
System.out.println(res);
于 2013-10-29T13:35:10.170 回答
1

像您对字段所做的所有更新updateInt都需要调用updateRow才能生效。这与滚动类型无关。根据特定的数据库,您甚至可以更新ResultSets TYPE_FORWARD_ONLY(如果支持,它是最快的选择)。唯一的限制是,它们必须是CONCUR_UPDATABLE.

您的第二个代码的错误是使用与获取ResultSet. 因此,ResultSet当您执行更新时,它变得无效。为此,您必须使用两个语句。

改变

Statement stmt = conn.createStatement(
  ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

String query = "SELECT user_id, first_name, last_name FROM Users";
ResultSet rs = stmt.executeQuery(query); // you use stmt here

String query2 = "INSERT INTO User VALUES (4, 'Joe', 'Bloggs')";
stmt.executeUpdate(query2); // here you use stmt again

Statement stmt = conn.createStatement(
  ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

String query = "SELECT user_id, first_name, last_name FROM Users";
ResultSet rs = stmt.executeQuery(query);

Statement stmt2 = conn.createStatement();// new statement for the insertion
String query2 = "INSERT INTO User VALUES (4, 'Joe', 'Bloggs')";
stmt2.executeUpdate(query2);
于 2013-10-29T15:25:56.523 回答
0

在从结果集对象迭代数据以首先查看更改时,您需要停止程序执行一段时间,因为您可以使用 System.in.read(),之后您可以转到数据库更改表数据并来程序查看结果集中的更新行在结果集对象上使用 refreshrow() 。您可以使用 refreshrow() 方法将更新的行数据从数据库获取到结果集。

Statement stmt = conn.createStatement(
  ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

  String query = "SELECT user_id, first_name, last_name FROM Users";
   ResultSet rs = stmt.executeQuery(query); // you use stmt here

    while(rs.next()){
     System.out.println("-----------------------------");
      System.in.read();
    System.out.println(rs.getInt(1));

   rs.refreshRow();
    System.out.println(rs.getString("first_name"));
    System.out.println(rs.getString("last_name"));
      }
于 2013-12-19T10:29:40.627 回答