OracleCachedRowSet обновляет данные в памяти без записи в базу данных
Я использую реализацию oracle jdbc cachedrowset для выбора нескольких строк, возвращаемых из запроса. Затем я обновляю некоторые данные, используя cachedrowset.updateInt() или другие методы обновления. Сначала я возвращаю курсор, используя cachedrowset.beforeFirst(), а затем снова перебираю набор строк для печати данных.
Дело в том, что данные, которые я получаю, используя getInt(), снова являются исходными данными. Я хочу получить данные, которые будут заменены исходными. Я не собираюсь вносить изменения в БД.
Я думал, что могу использовать объект Rowset в качестве оболочки данных без изменения каких-либо данных в БД, только для манипулирования данными и просмотра. Есть ли способ получить обновленную дату вместо оригинальной? Я не хотел кодировать собственный объект-обертку данных
Изменить: это, как я получаю данные, и ниже, как я обновляю их
public OracleCachedRowSet getCachedRowset( String query, Connection con)
throws DTSException {
try {
OracleCachedRowSet cachedRowSet = new OracleCachedRowSet();
cachedRowSet.setReadOnly(false);
cachedRowSet.setCommand(query);
cachedRowSet.execute(con);
return cachedRowSet;
} catch (SQLException sqle) {
throw new DTSException("Error fetching data! :" + sqle.getMessage(), sqle);
}
}
Обновить код:
public void updateRowSetData(CachedRowSet cachedRowSet, int columnIndex, int columnType, Object data)
throws SQLException {
switch (columnType) {
case Types.NUMERIC:
case Types.DECIMAL:
cachedRowSet.updateBigDecimal(columnIndex, (BigDecimal) data);
return;
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGNVARCHAR:
cachedRowSet.updateString(columnIndex, data == null ? null : data.toString());
return;
case Types.INTEGER:
cachedRowSet.updateInt(columnIndex, (Integer) data);
return;
case Types.DATE:
cachedRowSet.updateDate(columnIndex, (Date) data);
return;
case Types.TIMESTAMP:
cachedRowSet.updateTimestamp(columnIndex, (Timestamp) data);
return;
case Types.TIME:
cachedRowSet.updateTime(columnIndex, (Time) data);
return;
case Types.BIGINT:
cachedRowSet.updateLong(columnIndex, data == null ? null : Long.parseLong(data.toString()));
return;
case Types.DOUBLE:
case Types.FLOAT:
cachedRowSet.updateDouble(columnIndex, (Double) data);
return;
case Types.SMALLINT:
cachedRowSet.updateShort(columnIndex, data == null ? null : Short.parseShort(data.toString()));
return;
case Types.TINYINT:
cachedRowSet.updateByte(columnIndex, Byte.parseByte(data == null ? null : data.toString()));
return;
case Types.BINARY:
case Types.VARBINARY:
cachedRowSet.updateBytes(columnIndex, (byte[]) data);
return;
case Types.CLOB:
if (data != null) {
cachedRowSet.updateClob(columnIndex, ((Clob) data).getCharacterStream());
} else {
cachedRowSet.updateClob(columnIndex, (Clob) data);
}
return;
case Types.ARRAY:
cachedRowSet.updateArray(columnIndex, (Array) data);
return;
case Types.BLOB:
if (data != null) {
cachedRowSet.updateBlob(columnIndex, data == null ? null : ((Blob) data).getBinaryStream());
} else {
cachedRowSet.updateBlob(columnIndex, (Blob) data);
}
return;
case Types.REAL:
cachedRowSet.updateFloat(columnIndex, (Float) data);
return;
case Types.BIT:
case Types.BOOLEAN:
cachedRowSet.updateBoolean(columnIndex, (Boolean) data);
return;
case Types.REF:
cachedRowSet.updateRef(columnIndex, (Ref) data);
return;
case Types.LONGVARBINARY:
cachedRowSet.updateBinaryStream(columnIndex, (InputStream) data);
return;
default:
cachedRowSet.updateObject(columnIndex, data);
return;
}
}
2 ответа
Решением является вызов cachedRowSet.updateRow() после использования соответствующего метода обновления ( updateInt(), updateString() и т. Д.) Для внесения изменений, записанных в память. Я не использовал его раньше, потому что JavaDoc этого upateRow() говорит: "Обновляет базовую базу данных новым содержимым текущей строки этого объекта ResultSet".
Только это не то, что происходит. updateRow () обновляет данные в памяти, а не в базе данных. Я нашел решение в документе по ссылке: http://www.scribd.com/doc/68052701/8/Setting-Up-a-CachedRowSet-Object
Так что я просто позвонил updateRow после обновления данных:
while (cachedRowSet.next()) {
for (int i = 0; i < columnCount; i++) {
dataHandler.updateRowSetData(cachedRowSet, i + 1, columnTypes[i], getUpdatedData());
cachedRowSet.updateRow(); //Adding this line solves the problem. Otherwise changes are not made
}
}
Пожалуйста, попробуйте изменить настройки OracleCachedRowSet только для чтения следующим образом.
oracleCachedRowSet.setReadOnly(false);
Этот метод определен в javax.sql.RowSet, который реализуют классы набора строк.
РЕДАКТИРОВАТЬ: на основе кода, который вы опубликовали,
Вы правы, наблюдая, что вы делаете проход по значению. На самом деле, в java он всегда передается по значению и никогда не передается по ссылке.
Решение:
Прямо сейчас ваша функция возвращает void, измените это, чтобы вернуть обновленный cachedRowSet
, Ваше определение функции будет выглядеть
public CachedRowSet updateRowSetData(CachedRowSet cachedRowSet, int columnIndex, int columnType, Object data)
throws SQLException