Octave:如何从Java ResultSet对象检索数据?

Octave:如何从Java ResultSet对象检索数据?,octave,resultset,ojdbc,Octave,Resultset,Ojdbc,我需要向Octave实例提供从Oracle数据库检索的数据 我已经在Octave实例中实现了OJDBC连接,现在我可以将Oracle数据库中的数据放入Octave中的Java ResultSet对象(取自:): 但尚未成功从该结果集检索数据 如何将ResultSet对象中的八度数据放入数组或矩阵?我无法访问指定的.jar或合适的数据库来测试特定代码,但无论如何,这并不是八度的问题。实际上,您需要ResultSet类的相关api,以及处理它的标准方法。oracle建议在java中执行以下操作: w

我需要向Octave实例提供从Oracle数据库检索的数据

我已经在Octave实例中实现了OJDBC连接,现在我可以将Oracle数据库中的数据放入Octave中的Java ResultSet对象(取自:):

但尚未成功从该结果集检索数据


如何将ResultSet对象中的八度数据放入数组或矩阵?

我无法访问指定的.jar或合适的数据库来测试特定代码,但无论如何,这并不是八度的问题。实际上,您需要ResultSet类的相关api,以及处理它的标准方法。oracle建议在java中执行以下操作:

while(rs.next()){System.out.println(rs.getString(1));}
所以,除了通过octave的java接口之外,这大概也是octave中要做的事情。一种可能的方式是


而rs.next().booleanValue%本身就是一个布尔java对象
%不是八度音阶的有效逻辑输入
%“while”语句
%用rs做一些事情,例如填充单元格数组
循环结束
至于是否可以自动将java数组转换为倍频程单元对象,或者反之亦然,据我所知,这是不可能的。您必须通过for循环设置/获取元素,就像在java中一样(例如,请参阅手册中有关函数的说明)

了解如何操作
ResultSet
和相关类所需的文档位于中。(你不需要特定于Oracle的doco,除非你想做特定于Oracle的东西。所有JDBC驱动程序都符合通用的JDBCAPI。)看看这个和任何JDBC教程;因为它是一个Java对象,所以您将使用与Java代码相同的Octave方法调用

要转换为倍频程值,要知道Java原语会自动转换为倍频程类型,
Java.lang.String
对象需要通过调用
char(…)
进行转换,并且
Java.sql.Date
值必须手动转换为
datenums
。(惰性方法是获取字符串值并对其进行解析;快速方法是获取Unix时间值并进行数字转换。)

怎么办 由于Java JDBC每次将结果集游标向前推进一行,并且需要单独的方法调用来获取每列的值,因此需要使用一对嵌套循环来迭代结果集。像这样:

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 = 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
啊,但是如果你的列不全是数字呢?然后,您需要查看
rsMeta
中的列类型,打开它,并使用单元格数组来保存异构数据集。像这样:

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 = 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
您如何知道
数值类型
字符类型
等的值应该是什么?您必须检查
java.sql.Types
java类中的值。在运行时这样做,以确保与所运行的JDK一致

(注意:这段代码是一种简单、草率的方法。您可以(也应该)对其进行各种改进和优化。)

如何走得快 不幸的是,这种方法的性能将非常糟糕,因为来自Octave的Java方法调用非常昂贵,而且单元格保存数据的方式效率低下。如果结果集很大,为了获得良好的性能,您需要用Java编写一个结果集缓冲层,在Java中运行循环,并将结果缓冲在每列原始数组中,然后使用它。如果你想要一个如何做到这一点的例子,我有(M代码层)。请随意窃取代码。Octave不支持Java构造函数或类方法的点引用,因此要将其转换为Octave,需要用
javaObject
javaMethod
调用替换所有这些。(这很乏味,而且会产生难看的代码,所以我不打算自己做。对不起。)


如果您不愿意这样做(实际上是谁?),并且仍然需要良好的性能,那么您实际上应该做的是忘记将Octave直接连接到Oracle,然后编写一个单独的Python/NumPy或R程序来接受您的查询,并在Oracle db上运行它,并将结果写入一个
.mat
文件,然后从Octave读取。

请创建一个简单的示例以获得具体帮助。但是一般来说,octave的java接口可以在这里找到:你在寻找一种解析JSON结果的方法吗?@Andy我不知道结果集是什么样的数据结构。无论如何,我不想逐字解析它的内容,而是学习如何将内容放入一个八度对象(如数组或矩阵)中的无缝解决方案。如果有的话。例如R中有一个。@Tasos添加了我的代码。
ResultSet
将是一个实现。你不需要(也不应该关心)它的确切类型;只需针对
java.sql.ResultSet
接口API编写代码即可。“由于布尔java对象本身”–
rs.next()
返回一个基元
Boolean
,而不是
Boolean
对象,因此它通过八度自动转换为
逻辑
。您不需要调用
booleanValue()
,事实上它将不起作用。