我有一个oracle(10.2)PLSQL过程,该过程从sysrefcursor中的表中获取15条记录。 然后我将此游标作为结果集传递给java类。这个java类被加载到oracle。
驱动程序名称:Oracle JDBC驱动程序 驱动程序版本:10.2.0.1.0 司机主要版本:10 司机次要版本:2
观察:
1在java类中,当我遍历结果集时,我只得到前10条记录。
2如果光标被提取(20个或更多记录)或(10个或更少),我可以在迭代结果集时获得所有记录。
3我发现结果集的默认fetchsize是10.如果我将fetchSize更改为5,并且光标获取8条记录,我可以在迭代结果集时获得前5条记录。
4如果获取了光标(10个或更多记录)或(5个或更少),我可以在迭代结果集时获取所有记录。
5如果我将结果集fetchSize更改为1,无论光标获取多少记录,我都可以获得结果集中的所有记录。
为什么结果集表现得很奇怪?
public static BLOB createZip(BLOB prevBlob, String outPrefix, ResultSet entries, ResultSet rs, Long[] resultRows) throws Exception
{
OracleConnection conn = null;
BLOB retBLOB = null;
int page = 1;
int curRow = 0;
long totalRows = 0;
try
{
conn = (OracleConnection) new OracleDriver().defaultConnection();
ArrayList entryList = loadEntries(entries);
retBLOB = BLOB.createTemporary(conn, true, BLOB.DURATION_SESSION);
retBLOB.open(BLOB.MODE_READWRITE);
OutputStream bOut = retBLOB.setBinaryStream(0L);
ZipOutputStream zipOut = new ZipOutputStream(bOut);
PrintStream out = new PrintStream(zipOut);
zipOut.putNextEntry(new ZipEntry(outPrefix + "-p" + page + ".csv"));
writeHeader(out, entryList);
while (rs.next())
{
curRow++;
totalRows++;
if (curRow >= maxPageSize)
{
zipOut.closeEntry();
page++;
zipOut.putNextEntry(new ZipEntry(outPrefix + "-p" + page + ".csv"));
writeHeader(out, entryList);
curRow = 0;
}
for (int i = 0; i < entryList.size(); i++)
{
Entry e = (Entry) entryList.get(i);
if (i != 0)
{
out.print(",");
}
if (e.isEscape())
out.print("\"" + escapeExcel(rs.getString(e.getColumn())) + "\"");
else
out.print("\"" + emptyExcel(rs.getString(e.getColumn())) + "\"");
}
out.println();
}
if (totalRows == 0)
{
out.println("\"No Entries Found\"");
}
resultRows[0] = new Long(totalRows);
out.flush();
zipOut.closeEntry();
if (prevBlob != null)
{
byte[] buf = new byte[1024];
InputStream bIn = prevBlob.binaryStreamValue();
ZipInputStream zipIn = new ZipInputStream(bIn);
ZipEntry inEntry = zipIn.getNextEntry();
while (inEntry != null)
{
zipOut.putNextEntry(new ZipEntry(inEntry.getName()));
int len;
while ((len = zipIn.read(buf)) > 0) {
out.write(buf, 0, len);
}
inEntry = zipIn.getNextEntry();
}
zipIn.close();
try
{
prevBlob.freeTemporary();
}
catch (SQLException e) { }
}
zipOut.close();
retBLOB.close();
return retBLOB;
}
catch (Exception sex)
{
if (retBLOB != null)
{
try
{
retBLOB.freeTemporary();
}
catch (SQLException e) { }
}
throw sex;
}
finally
{
try { entries.close(); } catch (SQLException sex) { }
try { rs.close(); } catch (SQLException sex) { }
try
{
if (conn != null || !conn.isClosed())
{
conn.close();
}
}
catch (SQLException ex)
{
ex.printStackTrace();
}
}
}
答案 0 :(得分:2)
有一种解决方法。我在while(rs.next())
之前获取了列索引。
下面的代码段对我来说绝对没问题。但我仍然无法理解为什么resultSet.getString(columnName);
在while(rs.next())
内失败。
ArrayList entryList = loadEntries(entries);
int[] colIndx = new int[entryList.size()];
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
for (int i = 0; i < entryList.size(); i++){
Entry e = (Entry) entryList.get(i);
for (int j = 1; j <= numberOfColumns; j++){
if(rsmd.getColumnName(j).equalsIgnoreCase(e.getColumn()))
colIndx[i] = j;
}
}
try{
while (rs.next()){
for (int i = 0; i < colIndx.length ; i++){
System.out.println("Column Values["+colIndx[i]+"] : "+rs.getString(colIndx[i]));
}
}
}