Узнайте, что делать
Документы, которые вы хотите ResultSet
и связанные с ними классы, содержатся в документации Java JDBC API . (Вам не нужен специфичный для Oracle документ, если вы не хотите делать причудливые специфичные для Oracle вещи. Все драйверы JDBC соответствуют универсальному API JDBC.) Ознакомьтесь с этим и любым учебным пособием по JDBC; поскольку это объект Java, вы будете использовать те же вызовы методов из Octave, что и из кода Java.
Для преобразования в значения Octave следует знать, что примитивы Java автоматически преобразуются в типы Octave, java.lang.String
объекты требуют преобразования, вызывая для них char(...)
и значения java.sql.Date
, которые вам придется преобразовать в datenums
вручную. (Ленивый способ - получить их строковые значения и проанализировать их; быстрый способ - получить их значения времени Unix и преобразовать их численно.)
Что делать
Поскольку Java JDBC продвигает курсор результирующего набора по одной строке за раз и требует отдельного вызова метода для получения значения для каждого столбца, необходимо использовать пару вложенных циклов для итерации по ResultSet. Как это:
rsMeta = rs.getMetaData();
nCols = rsMeta.getColumnCount();
data = NaN(1, nCols);
iRow = 0;
while rs.next()
iRow = iRow + 1;
for iCol = 1:nCols
data(iRow,iCol) = rs.getDouble(iCol);
endfor
endwhile
Ах, а что если ваши столбцы не все числовые? Затем вам нужно взглянуть на тип столбца в rsMeta
, включить его и использовать массив ячеек для хранения гетерогенного набора данных. Как это:
rsMeta = rs.getMetaData();
nCols = rsMeta.getColumnCount();
data = cell(1, nCols);
iRow = 0;
while rs.next()
iRow = iRow + 1;
for iCol = 1:nCols
colTypeId = rsMeta.getColumnType(iCol);
switch colTypeId
case NUMERIC_TYPE
data{iRow,iCol} = rs.getDouble(iCol);
case CHAR_TYPE
data{iRow,iCol} = rs.getString(iCol);
data{iRow,iCol} = char(data{iRow,iCol});
# ... and so on ...
otherwise
error('Unsupported SQL data type in column %d: %d', ...
iCol, colTypeId);
endswitch
endfor
endwhile
Откуда вы знаете, какими должны быть значения для NUMERIC_TYPE
, CHAR_TYPE
и так далее? Вы должны проверить значения в java.sql.Types
Java-классе. Сделайте это во время выполнения, чтобы убедиться, что вы согласны с JDK, с которым вы работаете.
(Примечание: этот код - простой, неаккуратный способ сделать это. В него можно (и нужно) внести всевозможные улучшения и оптимизации.)
Как быстро ехать
К сожалению, производительность этого процесса составит большой отсос , потому что вызовы методов Java из Octave дороги, а ячейки неэффективно хранят данные. Если ваши результирующие наборы велики, чтобы получить хорошую производительность, вам нужно написать слой буферизации набора результатов в Java , который запускает циклы в Java и буферизует результаты в примитивных массивах для каждого столбца. и использовать это. Если вам нужен пример того, как это сделать, у меня есть пример реализации в Matlab в моей библиотеке Janklab (слой M-кода здесь ). Не стесняйтесь украсть код. Octave не поддерживает точечные ссылки на конструкторы Java или методы классов, поэтому для преобразования их в Octave вам необходимо заменить все эти вызовы javaObject
и javaMethod
. (Это утомительно и приводит к ужасному коду, поэтому я не собираюсь делать это сам. Извините.)
Если вы не хотите делать это (и действительно, кто?), И все еще нуждаетесь в хорошей производительности, вам нужно на самом деле сделать - забыть о подключении Octave напрямую к Oracle и написать отдельная программа Python / NumPy или R, которая принимает ваш запрос, запускает его для вашей базы данных Oracle и записывает результат в файл .mat
, который вы затем прочитаете из Octave.