2013-06-05 33 views
0

我正在使用Oracle數據庫10g,java並嘗試使用ResultSet插入新行。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 
*/ 
+5

通過執行語句獲取新的ResultSet,然後再次打印。 –

+0

難道這不是一個效率低下的解決方案嗎?如果你有大數據庫,那麼每次你輸入新記錄時,你都必須再次獲取所有行。 –

+0

它可能是*效益不大,但這就是它的工作原理。請注意,新行已添加到數據庫**,而不是從數據庫**恢復的當前行。因此,爲了識別新行,您必須對您的表進行另一次讀取。 –

回答

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; 
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()); 
+0

感謝分享知識,但我認爲Java的ResultSet與VB.Net的Dataset一樣工作,這就是我提出這個問題的原因 –

1

我記得有一個支持你正在尋找的功能,第三方庫,他們是相當昂貴的。

一般來說,是的,你將不得不重新檢索。但是,您可以聰明一點:您可以智能劃分查詢以獲取僅幾百行

  • 例如,通過使用兩個表格,一個用於生產數據,另一個用於生產數據,其他用於新數據,有時合併它們(您可以使用內存中的表格來創建新數據,並且如果需要,您可以創建交叉表格視圖,儘管不是必需的)
  • 你可以創建一個自動增量指標,只獲取最新的行,
  • 也可以在SQL Server中,LIMIT在MySQL等
  • ,當然,你可以實現自定義使用Oracle ROWNUMSELECT TOP數據庫驅動程序:-)

一般來說,如果你取超過幾百r定期流淌,有些事情是錯誤的,也許你應該重新考慮你的客戶端界面和實現。

1

A ResultSetTYPE_SCROLL_INSENSITIVE並不意味着要檢測對底層數據庫的更新(這就是不敏感這裏的含義)。如果您想要ResultSet檢測到更改,則應使用TYPE_SCROLL_SENSITIVE

但是,由於更改通常發生在不同的事務中,我相信大多數數據庫無法提供TYPE_SCROLL_SENSITIVE,如果他們可以,那麼他們可能只允許您查看所選行數據的更改,但不檢測更多(或刪除)行。

如果您嘗試使用TYPE_SCROLL_SENSITIVE,則可能需要檢查數據庫是否確實支持該類型(例如使用DatabaseMetaData.supportsResultSetType(int))。或者通過檢查創建的ResultSet是否實際上是指定類型(JDBC規範允許驅動程序在不支持的情況下「降級」類型和/或併發性)。

您可能還想檢查DatabaseMetaData.ownInsertsAreVisible(int)和相關的方法爲您的特定數據庫和驅動程序。