1

我正在使用 Oracle Database 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

4 回答 4

1

A ResultSetthat isTYPE_SCROLL_INSENSITIVE并不意味着检测对底层数据库的更新(这就是这里不敏感的意思)。如果要ResultSet检测更改,则应使用TYPE_SCROLL_SENSITIVE.

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

如果您尝试使用TYPE_SCROLL_SENSITIVE,您可能需要检查您的数据库是否确实支持该类型(例如使用DatabaseMetaData.supportsResultSetType(int))。或者通过检查 createdResultSet是否实际上是指定的类型(如果不支持,JDBC 规范允许驱动程序“降级”类型和/或并发性)。

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

于 2013-06-06T09:57:45.983 回答
1

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

一般来说,是的,您将不得不重新获取。但是,您可以聪明一点:您可以智能地对查询进行分区以仅获取几百行

  • 例如,通过使用两个表,一个用于生产数据,另一个用于新数据,有时还可以合并它们(您可以将内存表用于新数据,如果需要,您可以创建跨表视图,尽管不是必需的)
  • 您可以创建一个自动增量索引,并且只获取最新的行,
  • 或者您可以ROWNUM在 Oracle、SELECT TOPSQL Server、LIMITMySQL 等中使用。
  • 当然,您可以实现自定义数据库驱动程序 :-)

一般来说,如果您定期获取超过几百行,则可能有问题,也许您应该重新考虑您的客户端接口和实现。

于 2013-06-05T19:30:47.370 回答
1

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

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

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());
于 2013-06-05T19:16:07.537 回答
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;
于 2013-06-05T18:20:37.720 回答